]> Git Repo - linux.git/commitdiff
Merge tag 'loongarch-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuaca...
authorLinus Torvalds <[email protected]>
Mon, 22 Jul 2024 20:44:22 +0000 (13:44 -0700)
committerLinus Torvalds <[email protected]>
Mon, 22 Jul 2024 20:44:22 +0000 (13:44 -0700)
Pull LoongArch updates from Huacai Chen:

 - Define __ARCH_WANT_NEW_STAT in unistd.h

 - Always enumerate MADT and setup logical-physical CPU mapping

 - Add irq_work support via self IPIs

 - Add RANDOMIZE_KSTACK_OFFSET support

 - Add ARCH_HAS_PTE_DEVMAP support

 - Add ARCH_HAS_DEBUG_VM_PGTABLE support

 - Add writecombine support for DMW-based ioremap()

 - Add architectural preparation for CPUFreq

 - Add ACPI standard hardware register based S3 support

 - Add support for relocating the kernel with RELR relocation

 - Some bug fixes and other small changes

* tag 'loongarch-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  LoongArch: Make the users of larch_insn_gen_break() constant
  LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint
  LoongArch: Use rustc option -Zdirect-access-external-data
  LoongArch: Add support for relocating the kernel with RELR relocation
  LoongArch: Remove a redundant checking in relocator
  LoongArch: Use correct API to map cmdline in relocate_kernel()
  LoongArch: Automatically disable KASLR for hibernation
  LoongArch: Add ACPI standard hardware register based S3 support
  LoongArch: Add architectural preparation for CPUFreq
  LoongArch: Add writecombine support for DMW-based ioremap()
  LoongArch: Add ARCH_HAS_DEBUG_VM_PGTABLE support
  LoongArch: Add ARCH_HAS_PTE_DEVMAP support
  LoongArch: Add RANDOMIZE_KSTACK_OFFSET support
  LoongArch: Add irq_work support via self IPIs
  LoongArch: Always enumerate MADT and setup logical-physical CPU mapping
  LoongArch: Define __ARCH_WANT_NEW_STAT in unistd.h

1  2 
arch/loongarch/Kconfig
arch/loongarch/include/asm/loongarch.h
arch/loongarch/include/asm/pgtable.h
arch/loongarch/kernel/paravirt.c

diff --combined arch/loongarch/Kconfig
index b81d0eba5c7eb360ada69e726f0c7a2f1cfd81bb,f5df69ad70a661c1742c16e70bb5161396b4fe06..ebdb7156560c7bb17b612182605aac951a5b5b02
@@@ -16,12 -16,14 +16,14 @@@ config LOONGARC
        select ARCH_HAS_ACPI_TABLE_UPGRADE      if ACPI
        select ARCH_HAS_CPU_FINALIZE_INIT
        select ARCH_HAS_CURRENT_STACK_POINTER
+       select ARCH_HAS_DEBUG_VM_PGTABLE
        select ARCH_HAS_FAST_MULTIPLIER
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_KCOV
        select ARCH_HAS_KERNEL_FPU_SUPPORT if CPU_HAS_FPU
        select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
        select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+       select ARCH_HAS_PTE_DEVMAP
        select ARCH_HAS_PTE_SPECIAL
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
        select ARCH_INLINE_READ_LOCK if !PREEMPTION
        select HAVE_ARCH_KFENCE
        select HAVE_ARCH_KGDB if PERF_EVENTS
        select HAVE_ARCH_MMAP_RND_BITS if MMU
+       select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
        select HAVE_ARCH_SECCOMP
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
@@@ -607,6 -610,7 +610,7 @@@ config ARCH_HAS_GENERIC_CRASHKERNEL_RES
  
  config RELOCATABLE
        bool "Relocatable kernel"
+       select ARCH_HAS_RELR
        help
          This builds the kernel as a Position Independent Executable (PIE),
          which retains all relocation metadata required, so as to relocate
@@@ -649,17 -653,6 +653,17 @@@ config PARAVIR
          over full virtualization.  However, when run without a hypervisor
          the kernel is theoretically slower and slightly larger.
  
 +config PARAVIRT_TIME_ACCOUNTING
 +      bool "Paravirtual steal time accounting"
 +      depends on PARAVIRT
 +      help
 +        Select this option to enable fine granularity task steal time
 +        accounting. Time spent executing other tasks in parallel with
 +        the current vCPU is discounted from the vCPU power. To account for
 +        that, there can be a small performance impact.
 +
 +        If in doubt, say N here.
 +
  endmenu
  
  config ARCH_SELECT_MEMORY_MODEL
@@@ -710,6 -703,7 +714,7 @@@ config ARCH_HIBERNATION_POSSIBL
  
  source "kernel/power/Kconfig"
  source "drivers/acpi/Kconfig"
+ source "drivers/cpufreq/Kconfig"
  
  endmenu
  
index 7a4633ef284b73afb1fee87fca3ba0d2a5bd0b68,1501f0f8b06ee59db0a596273452e2208fce7656..04a78010fc725e5b484abf2830a90883c4a61cf6
  #define  KVM_SIGNATURE                        "KVM\0"
  #define CPUCFG_KVM_FEATURE            (CPUCFG_KVM_BASE + 4)
  #define  KVM_FEATURE_IPI              BIT(1)
 +#define  KVM_FEATURE_STEAL_TIME               BIT(2)
  
  #ifndef __ASSEMBLY__
  
  #define LOONGARCH_CSR_DMWIN2          0x182   /* 64 direct map win2: MEM */
  #define LOONGARCH_CSR_DMWIN3          0x183   /* 64 direct map win3: MEM */
  
- /* Direct Map window 0/1 */
+ /* Direct Map window 0/1/2/3 */
  #define CSR_DMW0_PLV0         _CONST64_(1 << 0)
  #define CSR_DMW0_VSEG         _CONST64_(0x8000)
  #define CSR_DMW0_BASE         (CSR_DMW0_VSEG << DMW_PABITS)
  #define CSR_DMW1_BASE         (CSR_DMW1_VSEG << DMW_PABITS)
  #define CSR_DMW1_INIT         (CSR_DMW1_BASE | CSR_DMW1_MAT | CSR_DMW1_PLV0)
  
+ #define CSR_DMW2_PLV0         _CONST64_(1 << 0)
+ #define CSR_DMW2_MAT          _CONST64_(2 << 4)
+ #define CSR_DMW2_VSEG         _CONST64_(0xa000)
+ #define CSR_DMW2_BASE         (CSR_DMW2_VSEG << DMW_PABITS)
+ #define CSR_DMW2_INIT         (CSR_DMW2_BASE | CSR_DMW2_MAT | CSR_DMW2_PLV0)
+ #define CSR_DMW3_INIT         0x0
  /* Performance Counter registers */
  #define LOONGARCH_CSR_PERFCTRL0               0x200   /* 32 perf event 0 config */
  #define LOONGARCH_CSR_PERFCNTR0               0x201   /* 64 perf event 0 count value */
  #define LOONGARCH_IOCSR_NODECNT               0x408
  
  #define LOONGARCH_IOCSR_MISC_FUNC     0x420
+ #define  IOCSR_MISC_FUNC_SOFT_INT     BIT_ULL(10)
  #define  IOCSR_MISC_FUNC_TIMER_RESET  BIT_ULL(21)
  #define  IOCSR_MISC_FUNC_EXT_IOI_EN   BIT_ULL(48)
  
  #define LOONGARCH_IOCSR_CPUTEMP               0x428
  
+ #define LOONGARCH_IOCSR_SMCMBX                0x51c
  /* PerCore CSR, only accessible by local cores */
  #define LOONGARCH_IOCSR_IPI_STATUS    0x1000
  #define LOONGARCH_IOCSR_IPI_EN                0x1004
index 161dd6e10479e536b2ef76a31c3152fc6f95cb84,0e821be6326893111b4f7fd23054e13350e73b83..3fbf1f37c58ecf6ee447adf4aeccd57d7a2bd538
@@@ -424,6 -424,9 +424,9 @@@ static inline int pte_special(pte_t pte
  static inline pte_t pte_mkspecial(pte_t pte)  { pte_val(pte) |= _PAGE_SPECIAL; return pte; }
  #endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */
  
+ static inline int pte_devmap(pte_t pte)               { return !!(pte_val(pte) & _PAGE_DEVMAP); }
+ static inline pte_t pte_mkdevmap(pte_t pte)   { pte_val(pte) |= _PAGE_DEVMAP; return pte; }
  #define pte_accessible pte_accessible
  static inline unsigned long pte_accessible(struct mm_struct *mm, pte_t a)
  {
@@@ -467,8 -470,8 +470,8 @@@ static inline void update_mmu_cache_ran
  #define update_mmu_cache(vma, addr, ptep) \
        update_mmu_cache_range(NULL, vma, addr, ptep, 1)
  
 -#define __HAVE_ARCH_UPDATE_MMU_TLB
 -#define update_mmu_tlb        update_mmu_cache
 +#define update_mmu_tlb_range(vma, addr, ptep, nr) \
 +      update_mmu_cache_range(NULL, vma, addr, ptep, nr)
  
  static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
                        unsigned long address, pmd_t *pmdp)
@@@ -558,6 -561,17 +561,17 @@@ static inline pmd_t pmd_mkyoung(pmd_t p
        return pmd;
  }
  
+ static inline int pmd_devmap(pmd_t pmd)
+ {
+       return !!(pmd_val(pmd) & _PAGE_DEVMAP);
+ }
+ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
+ {
+       pmd_val(pmd) |= _PAGE_DEVMAP;
+       return pmd;
+ }
  static inline struct page *pmd_page(pmd_t pmd)
  {
        if (pmd_trans_huge(pmd))
@@@ -613,6 -627,11 +627,11 @@@ static inline long pmd_protnone(pmd_t p
  #define pmd_leaf(pmd)         ((pmd_val(pmd) & _PAGE_HUGE) != 0)
  #define pud_leaf(pud)         ((pud_val(pud) & _PAGE_HUGE) != 0)
  
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ #define pud_devmap(pud)               (0)
+ #define pgd_devmap(pgd)               (0)
+ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
  /*
   * We provide our own get_unmapped area to cope with the virtual aliasing
   * constraints placed on us by the cache architecture.
index 9abe8b71aa48774e03081cb691fa0957a8c584a2,4272d24474453416096eaf2f209346ef37554f3a..9c9b75b76f62f298c89a14f520508e2d553f8a3f
@@@ -2,16 -2,14 +2,17 @@@
  #include <linux/export.h>
  #include <linux/types.h>
  #include <linux/interrupt.h>
+ #include <linux/irq_work.h>
  #include <linux/jump_label.h>
  #include <linux/kvm_para.h>
 +#include <linux/reboot.h>
  #include <linux/static_call.h>
  #include <asm/paravirt.h>
  
 +static int has_steal_clock;
  struct static_key paravirt_steal_enabled;
  struct static_key paravirt_steal_rq_enabled;
 +static DEFINE_PER_CPU(struct kvm_steal_time, steal_time) __aligned(64);
  
  static u64 native_steal_clock(int cpu)
  {
  
  DEFINE_STATIC_CALL(pv_steal_clock, native_steal_clock);
  
 +static bool steal_acc = true;
 +
 +static int __init parse_no_stealacc(char *arg)
 +{
 +      steal_acc = false;
 +      return 0;
 +}
 +early_param("no-steal-acc", parse_no_stealacc);
 +
 +static u64 paravt_steal_clock(int cpu)
 +{
 +      int version;
 +      u64 steal;
 +      struct kvm_steal_time *src;
 +
 +      src = &per_cpu(steal_time, cpu);
 +      do {
 +
 +              version = src->version;
 +              virt_rmb(); /* Make sure that the version is read before the steal */
 +              steal = src->steal;
 +              virt_rmb(); /* Make sure that the steal is read before the next version */
 +
 +      } while ((version & 1) || (version != src->version));
 +
 +      return steal;
 +}
 +
  #ifdef CONFIG_SMP
  static void pv_send_ipi_single(int cpu, unsigned int action)
  {
@@@ -128,6 -98,11 +129,11 @@@ static irqreturn_t pv_ipi_interrupt(in
                info->ipi_irqs[IPI_CALL_FUNCTION]++;
        }
  
+       if (action & SMP_IRQ_WORK) {
+               irq_work_run();
+               info->ipi_irqs[IPI_IRQ_WORK]++;
+       }
        return IRQ_HANDLED;
  }
  
@@@ -180,117 -155,3 +186,117 @@@ int __init pv_ipi_init(void
  
        return 0;
  }
 +
 +static int pv_enable_steal_time(void)
 +{
 +      int cpu = smp_processor_id();
 +      unsigned long addr;
 +      struct kvm_steal_time *st;
 +
 +      if (!has_steal_clock)
 +              return -EPERM;
 +
 +      st = &per_cpu(steal_time, cpu);
 +      addr = per_cpu_ptr_to_phys(st);
 +
 +      /* The whole structure kvm_steal_time should be in one page */
 +      if (PFN_DOWN(addr) != PFN_DOWN(addr + sizeof(*st))) {
 +              pr_warn("Illegal PV steal time addr %lx\n", addr);
 +              return -EFAULT;
 +      }
 +
 +      addr |= KVM_STEAL_PHYS_VALID;
 +      kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, KVM_FEATURE_STEAL_TIME, addr);
 +
 +      return 0;
 +}
 +
 +static void pv_disable_steal_time(void)
 +{
 +      if (has_steal_clock)
 +              kvm_hypercall2(KVM_HCALL_FUNC_NOTIFY, KVM_FEATURE_STEAL_TIME, 0);
 +}
 +
 +#ifdef CONFIG_SMP
 +static int pv_time_cpu_online(unsigned int cpu)
 +{
 +      unsigned long flags;
 +
 +      local_irq_save(flags);
 +      pv_enable_steal_time();
 +      local_irq_restore(flags);
 +
 +      return 0;
 +}
 +
 +static int pv_time_cpu_down_prepare(unsigned int cpu)
 +{
 +      unsigned long flags;
 +
 +      local_irq_save(flags);
 +      pv_disable_steal_time();
 +      local_irq_restore(flags);
 +
 +      return 0;
 +}
 +#endif
 +
 +static void pv_cpu_reboot(void *unused)
 +{
 +      pv_disable_steal_time();
 +}
 +
 +static int pv_reboot_notify(struct notifier_block *nb, unsigned long code, void *unused)
 +{
 +      on_each_cpu(pv_cpu_reboot, NULL, 1);
 +      return NOTIFY_DONE;
 +}
 +
 +static struct notifier_block pv_reboot_nb = {
 +      .notifier_call  = pv_reboot_notify,
 +};
 +
 +int __init pv_time_init(void)
 +{
 +      int r, feature;
 +
 +      if (!cpu_has_hypervisor)
 +              return 0;
 +      if (!kvm_para_available())
 +              return 0;
 +
 +      feature = read_cpucfg(CPUCFG_KVM_FEATURE);
 +      if (!(feature & KVM_FEATURE_STEAL_TIME))
 +              return 0;
 +
 +      has_steal_clock = 1;
 +      r = pv_enable_steal_time();
 +      if (r < 0) {
 +              has_steal_clock = 0;
 +              return 0;
 +      }
 +      register_reboot_notifier(&pv_reboot_nb);
 +
 +#ifdef CONFIG_SMP
 +      r = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
 +                                    "loongarch/pv_time:online",
 +                                    pv_time_cpu_online, pv_time_cpu_down_prepare);
 +      if (r < 0) {
 +              has_steal_clock = 0;
 +              pr_err("Failed to install cpu hotplug callbacks\n");
 +              return r;
 +      }
 +#endif
 +
 +      static_call_update(pv_steal_clock, paravt_steal_clock);
 +
 +      static_key_slow_inc(&paravirt_steal_enabled);
 +#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
 +      if (steal_acc)
 +              static_key_slow_inc(&paravirt_steal_rq_enabled);
 +#endif
 +
 +      pr_info("Using paravirt steal-time\n");
 +
 +      return 0;
 +}
This page took 0.103181 seconds and 4 git commands to generate.