Merge tag 'powerpc-4.20-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Nov 2018 16:19:35 +0000 (09:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Nov 2018 16:19:35 +0000 (09:19 -0700)
Pull powerpc fixes from Michael Ellerman:
 "Some things that I missed due to travel, or that came in late.

  Two fixes also going to stable:

   - A revert of a buggy change to the 8xx TLB miss handlers.

   - Our flushing of SPE (Signal Processing Engine) registers on fork
     was broken.

  Other changes:

   - A change to the KVM decrementer emulation to use proper APIs.

   - Some cleanups to the way we do code patching in the 8xx code.

   - Expose the maximum possible memory for the system in
     /proc/powerpc/lparcfg.

   - Merge some updates from Scott: "a couple device tree updates, and a
     fix for a missing prototype warning"

  A few other minor fixes and a handful of fixes for our selftests.

  Thanks to: Aravinda Prasad, Breno Leitao, Camelia Groza, Christophe
  Leroy, Felipe Rechia, Joel Stanley, Naveen N. Rao, Paul Mackerras,
  Scott Wood, Tyrel Datwyler"

* tag 'powerpc-4.20-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (21 commits)
  selftests/powerpc: Fix compilation issue due to asm label
  selftests/powerpc/cache_shape: Fix out-of-tree build
  selftests/powerpc/switch_endian: Fix out-of-tree build
  selftests/powerpc/pmu: Link ebb tests with -no-pie
  selftests/powerpc/signal: Fix out-of-tree build
  selftests/powerpc/ptrace: Fix out-of-tree build
  powerpc/xmon: Relax frame size for clang
  selftests: powerpc: Fix warning for security subdir
  selftests/powerpc: Relax L1d miss targets for rfi_flush test
  powerpc/process: Fix flush_all_to_thread for SPE
  powerpc/pseries: add missing cpumask.h include file
  selftests/powerpc: Fix ptrace tm failure
  KVM: PPC: Use exported tb_to_ns() function in decrementer emulation
  powerpc/pseries: Export maximum memory value
  powerpc/8xx: Use patch_site for perf counters setup
  powerpc/8xx: Use patch_site for memory setup patching
  powerpc/code-patching: Add a helper to get the address of a patch_site
  Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for CONFIG_SWAP"
  powerpc/8xx: add missing header in 8xx_mmu.c
  powerpc/8xx: Add DT node for using the SEC engine of the MPC885
  ...

22 files changed:
arch/powerpc/boot/dts/fsl/t2080rdb.dts
arch/powerpc/boot/dts/mpc885ads.dts
arch/powerpc/include/asm/code-patching.h
arch/powerpc/include/asm/mmu-8xx.h
arch/powerpc/include/asm/rtas.h
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/process.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/emulate.c
arch/powerpc/mm/8xx_mmu.c
arch/powerpc/perf/8xx-pmu.c
arch/powerpc/platforms/pseries/lparcfg.c
arch/powerpc/xmon/Makefile
tools/testing/selftests/powerpc/cache_shape/Makefile
tools/testing/selftests/powerpc/pmu/ebb/Makefile
tools/testing/selftests/powerpc/ptrace/Makefile
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
tools/testing/selftests/powerpc/security/Makefile
tools/testing/selftests/powerpc/security/rfi_flush.c
tools/testing/selftests/powerpc/signal/Makefile
tools/testing/selftests/powerpc/switch_endian/Makefile
tools/testing/selftests/powerpc/utils.c

index 55c0210..092a400 100644 (file)
                };
 
                ethernet@f0000 {
-                       phy-handle = <&xg_cs4315_phy1>;
+                       phy-handle = <&xg_cs4315_phy2>;
                        phy-connection-type = "xgmii";
                };
 
                ethernet@f2000 {
-                       phy-handle = <&xg_cs4315_phy2>;
+                       phy-handle = <&xg_cs4315_phy1>;
                        phy-connection-type = "xgmii";
                };
 
index 5b037f5..3aa300a 100644 (file)
@@ -72,7 +72,7 @@
                #address-cells = <1>;
                #size-cells = <1>;
                device_type = "soc";
-               ranges = <0x0 0xff000000 0x4000>;
+               ranges = <0x0 0xff000000 0x28000>;
                bus-frequency = <0>;
 
                // Temporary -- will go away once kernel uses ranges for get_immrbase().
                                #size-cells = <0>;
                        };
                };
+
+               crypto@20000 {
+                       compatible = "fsl,sec1.2", "fsl,sec1.0";
+                       reg = <0x20000 0x8000>;
+                       interrupts = <1 1>;
+                       interrupt-parent = <&PIC>;
+                       fsl,num-channels = <1>;
+                       fsl,channel-fifo-len = <24>;
+                       fsl,exec-units-mask = <0x4c>;
+                       fsl,descriptor-types-mask = <0x05000154>;
+               };
        };
 
        chosen {
index 31733a9..3d5acd2 100644 (file)
@@ -36,6 +36,11 @@ int raw_patch_instruction(unsigned int *addr, unsigned int instr);
 int patch_instruction_site(s32 *addr, unsigned int instr);
 int patch_branch_site(s32 *site, unsigned long target, int flags);
 
+static inline unsigned long patch_site_addr(s32 *site)
+{
+       return (unsigned long)site + *site;
+}
+
 int instr_is_relative_branch(unsigned int instr);
 int instr_is_relative_link_branch(unsigned int instr);
 int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
index 4f54775..fa05aa5 100644 (file)
  * respectively NA for All or X for Supervisor and no access for User.
  * Then we use the APG to say whether accesses are according to Page rules or
  * "all Supervisor" rules (Access to all)
- * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
- * When that bit is not set access is done iaw "all user"
- * which means no access iaw page rules.
- * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
- * 0x => No access => 11 (all accesses performed as user iaw page definition)
- * 10 => No user => 01 (all accesses performed according to page definition)
- * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
+ * Therefore, we define 2 APG groups. lsb is _PMD_USER
+ * 0 => No user => 01 (all accesses performed according to page definition)
+ * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
  * We define all 16 groups so that all other bits of APG can take any value
  */
-#ifdef CONFIG_SWAP
-#define MI_APG_INIT    0xf4f4f4f4
-#else
 #define MI_APG_INIT    0x44444444
-#endif
 
 /* The effective page number register.  When read, contains the information
  * about the last instruction TLB miss.  When MI_RPN is written, bits in
  * Supervisor and no access for user and NA for ALL.
  * Then we use the APG to say whether accesses are according to Page rules or
  * "all Supervisor" rules (Access to all)
- * We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
- * When that bit is not set access is done iaw "all user"
- * which means no access iaw page rules.
- * Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
- * 0x => No access => 11 (all accesses performed as user iaw page definition)
- * 10 => No user => 01 (all accesses performed according to page definition)
- * 11 => User => 00 (all accesses performed as supervisor iaw page definition)
+ * Therefore, we define 2 APG groups. lsb is _PMD_USER
+ * 0 => No user => 01 (all accesses performed according to page definition)
+ * 1 => User => 00 (all accesses performed as supervisor iaw page definition)
  * We define all 16 groups so that all other bits of APG can take any value
  */
-#ifdef CONFIG_SWAP
-#define MD_APG_INIT    0xf4f4f4f4
-#else
 #define MD_APG_INIT    0x44444444
-#endif
 
 /* The effective page number register.  When read, contains the information
  * about the last instruction TLB miss.  When MD_RPN is written, bits in
  */
 #define SPRN_M_TW      799
 
-/* APGs */
-#define M_APG0         0x00000000
-#define M_APG1         0x00000020
-#define M_APG2         0x00000040
-#define M_APG3         0x00000060
-
 #ifdef CONFIG_PPC_MM_SLICES
 #include <asm/nohash/32/slice.h>
 #define SLICE_ARRAY_SIZE       (1 << (32 - SLICE_LOW_SHIFT - 1))
@@ -251,6 +229,15 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
        BUG();
 }
 
+/* patch sites */
+extern s32 patch__itlbmiss_linmem_top;
+extern s32 patch__dtlbmiss_linmem_top, patch__dtlbmiss_immr_jmp;
+extern s32 patch__fixupdar_linmem_top;
+
+extern s32 patch__itlbmiss_exit_1, patch__itlbmiss_exit_2;
+extern s32 patch__dtlbmiss_exit_1, patch__dtlbmiss_exit_2, patch__dtlbmiss_exit_3;
+extern s32 patch__itlbmiss_perf, patch__dtlbmiss_perf;
+
 #endif /* !__ASSEMBLY__ */
 
 #if defined(CONFIG_PPC_4K_PAGES)
index bb38dd6..1b06add 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/spinlock.h>
 #include <asm/page.h>
 #include <linux/time.h>
+#include <linux/cpumask.h>
 
 /*
  * Definitions for talking to the RTAS on CHRP machines.
index 134a573..3b67b95 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/ptrace.h>
 #include <asm/export.h>
+#include <asm/code-patching-asm.h>
 
 #if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
 /* By simply checking Address >= 0x80000000, we know if its a kernel address */
@@ -318,8 +319,8 @@ InstructionTLBMiss:
        cmpli   cr0, r11, PAGE_OFFSET@h
 #ifndef CONFIG_PIN_TLB_TEXT
        /* It is assumed that kernel code fits into the first 8M page */
-_ENTRY(ITLBMiss_cmp)
-       cmpli   cr7, r11, (PAGE_OFFSET + 0x0800000)@h
+0:     cmpli   cr7, r11, (PAGE_OFFSET + 0x0800000)@h
+       patch_site      0b, patch__itlbmiss_linmem_top
 #endif
 #endif
 #endif
@@ -353,13 +354,14 @@ _ENTRY(ITLBMiss_cmp)
 #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
        mtcr    r12
 #endif
-
-#ifdef CONFIG_SWAP
-       rlwinm  r11, r10, 31, _PAGE_ACCESSED >> 1
-#endif
        /* Load the MI_TWC with the attributes for this "segment." */
        mtspr   SPRN_MI_TWC, r11        /* Set segment attributes */
 
+#ifdef CONFIG_SWAP
+       rlwinm  r11, r10, 32-5, _PAGE_PRESENT
+       and     r11, r11, r10
+       rlwimi  r10, r11, 0, _PAGE_PRESENT
+#endif
        li      r11, RPN_PATTERN | 0x200
        /* The Linux PTE won't go exactly into the MMU TLB.
         * Software indicator bits 20 and 23 must be clear.
@@ -372,16 +374,17 @@ _ENTRY(ITLBMiss_cmp)
        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 
        /* Restore registers */
-_ENTRY(itlb_miss_exit_1)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
 #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
        mfspr   r12, SPRN_SPRG_SCRATCH2
 #endif
        rfi
+       patch_site      0b, patch__itlbmiss_exit_1
+
 #ifdef CONFIG_PERF_EVENTS
-_ENTRY(itlb_miss_perf)
-       lis     r10, (itlb_miss_counter - PAGE_OFFSET)@ha
+       patch_site      0f, patch__itlbmiss_perf
+0:     lis     r10, (itlb_miss_counter - PAGE_OFFSET)@ha
        lwz     r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
        addi    r11, r11, 1
        stw     r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
@@ -435,11 +438,11 @@ DataStoreTLBMiss:
 #ifndef CONFIG_PIN_TLB_IMMR
        cmpli   cr0, r11, VIRT_IMMR_BASE@h
 #endif
-_ENTRY(DTLBMiss_cmp)
-       cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+0:     cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+       patch_site      0b, patch__dtlbmiss_linmem_top
 #ifndef CONFIG_PIN_TLB_IMMR
-_ENTRY(DTLBMiss_jmp)
-       beq-    DTLBMissIMMR
+0:     beq-    DTLBMissIMMR
+       patch_site      0b, patch__dtlbmiss_immr_jmp
 #endif
        blt     cr7, DTLBMissLinear
        lis     r11, (swapper_pg_dir-PAGE_OFFSET)@ha
@@ -470,14 +473,22 @@ _ENTRY(DTLBMiss_jmp)
         * above.
         */
        rlwimi  r11, r10, 0, _PAGE_GUARDED
-#ifdef CONFIG_SWAP
-       /* _PAGE_ACCESSED has to be set. We use second APG bit for that, 0
-        * on that bit will represent a Non Access group
-        */
-       rlwinm  r11, r10, 31, _PAGE_ACCESSED >> 1
-#endif
        mtspr   SPRN_MD_TWC, r11
 
+       /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
+        * We also need to know if the insn is a load/store, so:
+        * Clear _PAGE_PRESENT and load that which will
+        * trap into DTLB Error with store bit set accordinly.
+        */
+       /* PRESENT=0x1, ACCESSED=0x20
+        * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
+        * r10 = (r10 & ~PRESENT) | r11;
+        */
+#ifdef CONFIG_SWAP
+       rlwinm  r11, r10, 32-5, _PAGE_PRESENT
+       and     r11, r11, r10
+       rlwimi  r10, r11, 0, _PAGE_PRESENT
+#endif
        /* The Linux PTE won't go exactly into the MMU TLB.
         * Software indicator bits 24, 25, 26, and 27 must be
         * set.  All other Linux PTE bits control the behavior
@@ -489,14 +500,16 @@ _ENTRY(DTLBMiss_jmp)
 
        /* Restore registers */
        mtspr   SPRN_DAR, r11   /* Tag DAR */
-_ENTRY(dtlb_miss_exit_1)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__dtlbmiss_exit_1
+
 #ifdef CONFIG_PERF_EVENTS
-_ENTRY(dtlb_miss_perf)
-       lis     r10, (dtlb_miss_counter - PAGE_OFFSET)@ha
+       patch_site      0f, patch__dtlbmiss_perf
+0:     lis     r10, (dtlb_miss_counter - PAGE_OFFSET)@ha
        lwz     r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
        addi    r11, r11, 1
        stw     r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
@@ -637,8 +650,8 @@ InstructionBreakpoint:
  */
 DTLBMissIMMR:
        mtcr    r12
-       /* Set 512k byte guarded page and mark it valid and accessed */
-       li      r10, MD_PS512K | MD_GUARDED | MD_SVALID | M_APG2
+       /* Set 512k byte guarded page and mark it valid */
+       li      r10, MD_PS512K | MD_GUARDED | MD_SVALID
        mtspr   SPRN_MD_TWC, r10
        mfspr   r10, SPRN_IMMR                  /* Get current IMMR */
        rlwinm  r10, r10, 0, 0xfff80000         /* Get 512 kbytes boundary */
@@ -648,16 +661,17 @@ DTLBMissIMMR:
 
        li      r11, RPN_PATTERN
        mtspr   SPRN_DAR, r11   /* Tag DAR */
-_ENTRY(dtlb_miss_exit_2)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__dtlbmiss_exit_2
 
 DTLBMissLinear:
        mtcr    r12
-       /* Set 8M byte page and mark it valid and accessed */
-       li      r11, MD_PS8MEG | MD_SVALID | M_APG2
+       /* Set 8M byte page and mark it valid */
+       li      r11, MD_PS8MEG | MD_SVALID
        mtspr   SPRN_MD_TWC, r11
        rlwinm  r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
        ori     r10, r10, 0xf0 | MD_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
@@ -666,28 +680,29 @@ DTLBMissLinear:
 
        li      r11, RPN_PATTERN
        mtspr   SPRN_DAR, r11   /* Tag DAR */
-_ENTRY(dtlb_miss_exit_3)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__dtlbmiss_exit_3
 
 #ifndef CONFIG_PIN_TLB_TEXT
 ITLBMissLinear:
        mtcr    r12
-       /* Set 8M byte page and mark it valid,accessed */
-       li      r11, MI_PS8MEG | MI_SVALID | M_APG2
+       /* Set 8M byte page and mark it valid */
+       li      r11, MI_PS8MEG | MI_SVALID
        mtspr   SPRN_MI_TWC, r11
        rlwinm  r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
        ori     r10, r10, 0xf0 | MI_SPS16K | _PAGE_SH | _PAGE_DIRTY | \
                          _PAGE_PRESENT
        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 
-_ENTRY(itlb_miss_exit_2)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
+0:     mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
        mfspr   r12, SPRN_SPRG_SCRATCH2
        rfi
+       patch_site      0b, patch__itlbmiss_exit_2
 #endif
 
 /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
@@ -705,8 +720,10 @@ FixupDAR:/* Entry point for dcbx workaround. */
        mfspr   r11, SPRN_M_TW  /* Get level 1 table */
        blt+    3f
        rlwinm  r11, r10, 16, 0xfff8
-_ENTRY(FixupDAR_cmp)
-       cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+
+0:     cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
+       patch_site      0b, patch__fixupdar_linmem_top
+
        /* create physical page address from effective address */
        tophys(r11, r10)
        blt-    cr7, 201f
@@ -960,7 +977,7 @@ initial_mmu:
        ori     r8, r8, MI_EVALID       /* Mark it valid */
        mtspr   SPRN_MI_EPN, r8
        li      r8, MI_PS8MEG /* Set 8M byte page */
-       ori     r8, r8, MI_SVALID | M_APG2      /* Make it valid, APG 2 */
+       ori     r8, r8, MI_SVALID       /* Make it valid */
        mtspr   SPRN_MI_TWC, r8
        li      r8, MI_BOOTINIT         /* Create RPN for address 0 */
        mtspr   SPRN_MI_RPN, r8         /* Store TLB entry */
@@ -987,7 +1004,7 @@ initial_mmu:
        ori     r8, r8, MD_EVALID       /* Mark it valid */
        mtspr   SPRN_MD_EPN, r8
        li      r8, MD_PS512K | MD_GUARDED      /* Set 512k byte page */
-       ori     r8, r8, MD_SVALID | M_APG2      /* Make it valid and accessed */
+       ori     r8, r8, MD_SVALID       /* Make it valid */
        mtspr   SPRN_MD_TWC, r8
        mr      r8, r9                  /* Create paddr for TLB */
        ori     r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
index 4d5322c..96f3473 100644 (file)
@@ -590,12 +590,11 @@ void flush_all_to_thread(struct task_struct *tsk)
        if (tsk->thread.regs) {
                preempt_disable();
                BUG_ON(tsk != current);
-               save_all(tsk);
-
 #ifdef CONFIG_SPE
                if (tsk->thread.regs->msr & MSR_SPE)
                        tsk->thread.spefscr = mfspr(SPRN_SPEFSCR);
 #endif
+               save_all(tsk);
 
                preempt_enable();
        }
index bf8def2..d65b961 100644 (file)
@@ -2337,8 +2337,7 @@ static void kvmppc_set_timer(struct kvm_vcpu *vcpu)
                kvmppc_core_prepare_to_enter(vcpu);
                return;
        }
-       dec_nsec = (vcpu->arch.dec_expires - now) * NSEC_PER_SEC
-                  / tb_ticks_per_sec;
+       dec_nsec = tb_to_ns(vcpu->arch.dec_expires - now);
        hrtimer_start(&vcpu->arch.dec_timer, dec_nsec, HRTIMER_MODE_REL);
        vcpu->arch.timer_running = 1;
 }
index fa888bf..9f5b8c0 100644 (file)
@@ -61,11 +61,10 @@ void kvmppc_emulate_dec(struct kvm_vcpu *vcpu)
 
        dec_time = vcpu->arch.dec;
        /*
-        * Guest timebase ticks at the same frequency as host decrementer.
-        * So use the host decrementer calculations for decrementer emulation.
+        * Guest timebase ticks at the same frequency as host timebase.
+        * So use the host timebase calculations for decrementer emulation.
         */
-       dec_time = dec_time << decrementer_clockevent.shift;
-       do_div(dec_time, decrementer_clockevent.mult);
+       dec_time = tb_to_ns(dec_time);
        dec_nsec = do_div(dec_time, NSEC_PER_SEC);
        hrtimer_start(&vcpu->arch.dec_timer,
                ktime_set(dec_time, dec_nsec), HRTIMER_MODE_REL);
index 36484a2..01b7f51 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/memblock.h>
+#include <linux/mmu_context.h>
 #include <asm/fixmap.h>
 #include <asm/code-patching.h>
 
@@ -79,7 +80,7 @@ void __init MMU_init_hw(void)
        for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) {
                mtspr(SPRN_MD_CTR, ctr | (i << 8));
                mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID);
-               mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID | M_APG2);
+               mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID);
                mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT);
                addr += LARGE_PAGE_SIZE_8M;
                mem -= LARGE_PAGE_SIZE_8M;
@@ -97,22 +98,13 @@ static void __init mmu_mapin_immr(void)
                map_kernel_page(v + offset, p + offset, PAGE_KERNEL_NCG);
 }
 
-/* Address of instructions to patch */
-#ifndef CONFIG_PIN_TLB_IMMR
-extern unsigned int DTLBMiss_jmp;
-#endif
-extern unsigned int DTLBMiss_cmp, FixupDAR_cmp;
-#ifndef CONFIG_PIN_TLB_TEXT
-extern unsigned int ITLBMiss_cmp;
-#endif
-
-static void __init mmu_patch_cmp_limit(unsigned int *addr, unsigned long mapped)
+static void __init mmu_patch_cmp_limit(s32 *site, unsigned long mapped)
 {
-       unsigned int instr = *addr;
+       unsigned int instr = *(unsigned int *)patch_site_addr(site);
 
        instr &= 0xffff0000;
        instr |= (unsigned long)__va(mapped) >> 16;
-       patch_instruction(addr, instr);
+       patch_instruction_site(site, instr);
 }
 
 unsigned long __init mmu_mapin_ram(unsigned long top)
@@ -123,17 +115,17 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
                mapped = 0;
                mmu_mapin_immr();
 #ifndef CONFIG_PIN_TLB_IMMR
-               patch_instruction(&DTLBMiss_jmp, PPC_INST_NOP);
+               patch_instruction_site(&patch__dtlbmiss_immr_jmp, PPC_INST_NOP);
 #endif
 #ifndef CONFIG_PIN_TLB_TEXT
-               mmu_patch_cmp_limit(&ITLBMiss_cmp, 0);
+               mmu_patch_cmp_limit(&patch__itlbmiss_linmem_top, 0);
 #endif
        } else {
                mapped = top & ~(LARGE_PAGE_SIZE_8M - 1);
        }
 
-       mmu_patch_cmp_limit(&DTLBMiss_cmp, mapped);
-       mmu_patch_cmp_limit(&FixupDAR_cmp, mapped);
+       mmu_patch_cmp_limit(&patch__dtlbmiss_linmem_top, mapped);
+       mmu_patch_cmp_limit(&patch__fixupdar_linmem_top, mapped);
 
        /* If the size of RAM is not an exact power of two, we may not
         * have covered RAM in its entirety with 8 MiB
index 6c0020d..e38f74e 100644 (file)
@@ -31,9 +31,6 @@
 
 extern unsigned long itlb_miss_counter, dtlb_miss_counter;
 extern atomic_t instruction_counter;
-extern unsigned int itlb_miss_perf, dtlb_miss_perf;
-extern unsigned int itlb_miss_exit_1, itlb_miss_exit_2;
-extern unsigned int dtlb_miss_exit_1, dtlb_miss_exit_2, dtlb_miss_exit_3;
 
 static atomic_t insn_ctr_ref;
 static atomic_t itlb_miss_ref;
@@ -103,22 +100,22 @@ static int mpc8xx_pmu_add(struct perf_event *event, int flags)
                break;
        case PERF_8xx_ID_ITLB_LOAD_MISS:
                if (atomic_inc_return(&itlb_miss_ref) == 1) {
-                       unsigned long target = (unsigned long)&itlb_miss_perf;
+                       unsigned long target = patch_site_addr(&patch__itlbmiss_perf);
 
-                       patch_branch(&itlb_miss_exit_1, target, 0);
+                       patch_branch_site(&patch__itlbmiss_exit_1, target, 0);
 #ifndef CONFIG_PIN_TLB_TEXT
-                       patch_branch(&itlb_miss_exit_2, target, 0);
+                       patch_branch_site(&patch__itlbmiss_exit_2, target, 0);
 #endif
                }
                val = itlb_miss_counter;
                break;
        case PERF_8xx_ID_DTLB_LOAD_MISS:
                if (atomic_inc_return(&dtlb_miss_ref) == 1) {
-                       unsigned long target = (unsigned long)&dtlb_miss_perf;
+                       unsigned long target = patch_site_addr(&patch__dtlbmiss_perf);
 
-                       patch_branch(&dtlb_miss_exit_1, target, 0);
-                       patch_branch(&dtlb_miss_exit_2, target, 0);
-                       patch_branch(&dtlb_miss_exit_3, target, 0);
+                       patch_branch_site(&patch__dtlbmiss_exit_1, target, 0);
+                       patch_branch_site(&patch__dtlbmiss_exit_2, target, 0);
+                       patch_branch_site(&patch__dtlbmiss_exit_3, target, 0);
                }
                val = dtlb_miss_counter;
                break;
@@ -180,17 +177,17 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags)
                break;
        case PERF_8xx_ID_ITLB_LOAD_MISS:
                if (atomic_dec_return(&itlb_miss_ref) == 0) {
-                       patch_instruction(&itlb_miss_exit_1, insn);
+                       patch_instruction_site(&patch__itlbmiss_exit_1, insn);
 #ifndef CONFIG_PIN_TLB_TEXT
-                       patch_instruction(&itlb_miss_exit_2, insn);
+                       patch_instruction_site(&patch__itlbmiss_exit_2, insn);
 #endif
                }
                break;
        case PERF_8xx_ID_DTLB_LOAD_MISS:
                if (atomic_dec_return(&dtlb_miss_ref) == 0) {
-                       patch_instruction(&dtlb_miss_exit_1, insn);
-                       patch_instruction(&dtlb_miss_exit_2, insn);
-                       patch_instruction(&dtlb_miss_exit_3, insn);
+                       patch_instruction_site(&patch__dtlbmiss_exit_1, insn);
+                       patch_instruction_site(&patch__dtlbmiss_exit_2, insn);
+                       patch_instruction_site(&patch__dtlbmiss_exit_3, insn);
                }
                break;
        }
index 8bd590a..7944873 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/hugetlb.h>
 #include <asm/lppaca.h>
 #include <asm/hvcall.h>
 #include <asm/firmware.h>
@@ -36,6 +37,7 @@
 #include <asm/vio.h>
 #include <asm/mmu.h>
 #include <asm/machdep.h>
+#include <asm/drmem.h>
 
 #include "pseries.h"
 
@@ -433,6 +435,16 @@ static void parse_em_data(struct seq_file *m)
                seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
 }
 
+static void maxmem_data(struct seq_file *m)
+{
+       unsigned long maxmem = 0;
+
+       maxmem += drmem_info->n_lmbs * drmem_info->lmb_size;
+       maxmem += hugetlb_total_pages() * PAGE_SIZE;
+
+       seq_printf(m, "MaxMem=%ld\n", maxmem);
+}
+
 static int pseries_lparcfg_data(struct seq_file *m, void *v)
 {
        int partition_potential_processors;
@@ -491,6 +503,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
        seq_printf(m, "slb_size=%d\n", mmu_slb_size);
 #endif
        parse_em_data(m);
+       maxmem_data(m);
 
        return 0;
 }
index 69e7fb4..878f9c1 100644 (file)
@@ -11,6 +11,12 @@ UBSAN_SANITIZE := n
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS))
 
+ifdef CONFIG_CC_IS_CLANG
+# clang stores addresses on the stack causing the frame size to blow
+# out. See https://github.com/ClangBuiltLinux/linux/issues/252
+KBUILD_CFLAGS += -Wframe-larger-than=4096
+endif
+
 ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
 
 obj-y                  += xmon.o nonstdio.o spr_access.o
index ede4d3d..689f6c8 100644 (file)
@@ -1,12 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
-TEST_PROGS := cache_shape
-
-all: $(TEST_PROGS)
-
-$(TEST_PROGS): ../harness.c ../utils.c
+TEST_GEN_PROGS := cache_shape
 
 top_srcdir = ../../../../..
 include ../../lib.mk
 
-clean:
-       rm -f $(TEST_PROGS) *.o
+$(TEST_GEN_PROGS): ../harness.c ../utils.c
index bd5dfa5..23f4caf 100644 (file)
@@ -5,6 +5,9 @@ noarg:
 # The EBB handler is 64-bit code and everything links against it
 CFLAGS += -m64
 
+# Toolchains may build PIE by default which breaks the assembly
+LDFLAGS += -no-pie
+
 TEST_GEN_PROGS := reg_access_test event_attributes_test cycles_test    \
         cycles_with_freeze_test pmc56_overflow_test            \
         ebb_vs_cpu_event_test cpu_event_vs_ebb_test            \
index 9b35ca8..8d3f006 100644 (file)
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-TEST_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
+TEST_GEN_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
               ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \
               ptrace-tm-spd-vsx ptrace-tm-spr ptrace-hwbreak ptrace-pkey core-pkey \
               perf-hwbreak ptrace-syscall
@@ -7,14 +7,9 @@ TEST_PROGS := ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
 top_srcdir = ../../../../..
 include ../../lib.mk
 
-all: $(TEST_PROGS)
-
 CFLAGS += -m64 -I../../../../../usr/include -I../tm -mhtm -fno-pie
 
-ptrace-pkey core-pkey: child.h
-ptrace-pkey core-pkey: LDLIBS += -pthread
-
-$(TEST_PROGS): ../harness.c ../utils.c ../lib/reg.S ptrace.h
+$(OUTPUT)/ptrace-pkey $(OUTPUT)/core-pkey: child.h
+$(OUTPUT)/ptrace-pkey $(OUTPUT)/core-pkey: LDLIBS += -pthread
 
-clean:
-       rm -f $(TEST_PROGS) *.o
+$(TEST_GEN_PROGS): ../harness.c ../utils.c ../lib/reg.S ptrace.h
index 327fa94..dbdffa2 100644 (file)
@@ -67,8 +67,8 @@ trans:
                "3: ;"
                : [res] "=r" (result), [texasr] "=r" (texasr)
                : [gpr_1]"i"(GPR_1), [gpr_2]"i"(GPR_2), [gpr_4]"i"(GPR_4),
-               [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "r" (&a),
-               [flt_2] "r" (&b), [flt_4] "r" (&d)
+               [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a),
+               [flt_4] "b" (&d)
                : "memory", "r5", "r6", "r7",
                "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
                "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
index 44690f1..85861c4 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0+
 
 TEST_GEN_PROGS := rfi_flush
+top_srcdir = ../../../../..
 
 CFLAGS += -I../../../../../usr/include
 
index 564ed45..0a7d0af 100644 (file)
@@ -49,6 +49,7 @@ int rfi_flush_test(void)
        struct perf_event_read v;
        __u64 l1d_misses_total = 0;
        unsigned long iterations = 100000, zero_size = 24 * 1024;
+       unsigned long l1d_misses_expected;
        int rfi_flush_org, rfi_flush;
 
        SKIP_IF(geteuid() != 0);
@@ -71,6 +72,12 @@ int rfi_flush_test(void)
 
        iter = repetitions;
 
+       /*
+        * We expect to see l1d miss for each cacheline access when rfi_flush
+        * is set. Allow a small variation on this.
+        */
+       l1d_misses_expected = iterations * (zero_size / CACHELINE_SIZE - 2);
+
 again:
        FAIL_IF(perf_event_reset(fd));
 
@@ -78,10 +85,9 @@ again:
 
        FAIL_IF(read(fd, &v, sizeof(v)) != sizeof(v));
 
-       /* Expect at least zero_size/CACHELINE_SIZE misses per iteration */
-       if (v.l1d_misses >= (iterations * zero_size / CACHELINE_SIZE) && rfi_flush)
+       if (rfi_flush && v.l1d_misses >= l1d_misses_expected)
                passes++;
-       else if (v.l1d_misses < iterations && !rfi_flush)
+       else if (!rfi_flush && v.l1d_misses < (l1d_misses_expected / 2))
                passes++;
 
        l1d_misses_total += v.l1d_misses;
@@ -92,13 +98,15 @@ again:
        if (passes < repetitions) {
                printf("FAIL (L1D misses with rfi_flush=%d: %llu %c %lu) [%d/%d failures]\n",
                       rfi_flush, l1d_misses_total, rfi_flush ? '<' : '>',
-                      rfi_flush ? (repetitions * iterations * zero_size / CACHELINE_SIZE) : iterations,
+                      rfi_flush ? repetitions * l1d_misses_expected :
+                      repetitions * l1d_misses_expected / 2,
                       repetitions - passes, repetitions);
                rc = 1;
        } else
                printf("PASS (L1D misses with rfi_flush=%d: %llu %c %lu) [%d/%d pass]\n",
                       rfi_flush, l1d_misses_total, rfi_flush ? '>' : '<',
-                      rfi_flush ? (repetitions * iterations * zero_size / CACHELINE_SIZE) : iterations,
+                      rfi_flush ? repetitions * l1d_misses_expected :
+                      repetitions * l1d_misses_expected / 2,
                       passes, repetitions);
 
        if (rfi_flush == rfi_flush_org) {
index 1fca25c..209a958 100644 (file)
@@ -1,15 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0
-TEST_PROGS := signal signal_tm
-
-all: $(TEST_PROGS)
-
-$(TEST_PROGS): ../harness.c ../utils.c signal.S
+TEST_GEN_PROGS := signal signal_tm
 
 CFLAGS += -maltivec
-signal_tm: CFLAGS += -mhtm
+$(OUTPUT)/signal_tm: CFLAGS += -mhtm
 
 top_srcdir = ../../../../..
 include ../../lib.mk
 
-clean:
-       rm -f $(TEST_PROGS) *.o
+$(TEST_GEN_PROGS): ../harness.c ../utils.c signal.S
index fcd2dcb..bdc081a 100644 (file)
@@ -8,6 +8,7 @@ EXTRA_CLEAN = $(OUTPUT)/*.o $(OUTPUT)/check-reversed.S
 top_srcdir = ../../../../..
 include ../../lib.mk
 
+$(OUTPUT)/switch_endian_test: ASFLAGS += -I $(OUTPUT)
 $(OUTPUT)/switch_endian_test: $(OUTPUT)/check-reversed.S
 
 $(OUTPUT)/check-reversed.o: $(OUTPUT)/check.o
index 43c3428..ed62f41 100644 (file)
@@ -25,7 +25,6 @@
 #include "utils.h"
 
 static char auxv[4096];
-extern unsigned int dscr_insn[];
 
 int read_auxv(char *buf, ssize_t buf_size)
 {
@@ -247,7 +246,8 @@ static void sigill_handler(int signr, siginfo_t *info, void *unused)
        ucontext_t *ctx = (ucontext_t *)unused;
        unsigned long *pc = &UCONTEXT_NIA(ctx);
 
-       if (*pc == (unsigned long)&dscr_insn) {
+       /* mtspr 3,RS to check for move to DSCR below */
+       if ((*((unsigned int *)*pc) & 0xfc1fffff) == 0x7c0303a6) {
                if (!warned++)
                        printf("WARNING: Skipping over dscr setup. Consider running 'ppc64_cpu --dscr=1' manually.\n");
                *pc += 4;
@@ -271,5 +271,5 @@ void set_dscr(unsigned long val)
                init = 1;
        }
 
-       asm volatile("dscr_insn: mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR));
+       asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR));
 }