]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
powerpc/mm: Remove kvm radix prefetch workaround for Power9 DD2.2
authorJordan Niethe <jniethe5@gmail.com>
Fri, 6 Dec 2019 03:17:22 +0000 (14:17 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 25 Jan 2020 13:11:37 +0000 (00:11 +1100)
Commit a25bd72badfa ("powerpc/mm/radix: Workaround prefetch issue with
KVM") introduced a number of workarounds as coming out of a guest with
the mmu enabled would make the cpu would start running in hypervisor
state with the PID value from the guest. The cpu will then start
prefetching for the hypervisor with that PID value.

In Power9 DD2.2 the cpu behaviour was modified to fix this. When
accessing Quadrant 0 in hypervisor mode with LPID != 0 prefetching will
not be performed. This means that we can get rid of the workarounds for
Power9 DD2.2 and later revisions. Add a new cpu feature
CPU_FTR_P9_RADIX_PREFETCH_BUG to indicate if the workarounds are needed.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
Acked-by: Paul Mackerras <paulus@ozlabs.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20191206031722.25781-1-jniethe5@gmail.com
arch/powerpc/include/asm/cputable.h
arch/powerpc/kernel/dt_cpu_ftrs.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/mm/book3s64/radix_pgtable.c
arch/powerpc/mm/book3s64/radix_tlb.c

index cf00ff0d121def10d7afb75b9d5d6619a32667b7..40a4d3c6fd9916b06622b12238c6b51f41900d6f 100644 (file)
@@ -212,6 +212,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_P9_TLBIE_STQ_BUG       LONG_ASM_CONST(0x0000400000000000)
 #define CPU_FTR_P9_TIDR                        LONG_ASM_CONST(0x0000800000000000)
 #define CPU_FTR_P9_TLBIE_ERAT_BUG      LONG_ASM_CONST(0x0001000000000000)
+#define CPU_FTR_P9_RADIX_PREFETCH_BUG  LONG_ASM_CONST(0x0002000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -459,8 +460,10 @@ static inline void cpu_feature_keys_init(void) { }
            CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
            CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
            CPU_FTR_P9_TLBIE_STQ_BUG | CPU_FTR_P9_TLBIE_ERAT_BUG | CPU_FTR_P9_TIDR)
-#define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
-#define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1)
+#define CPU_FTRS_POWER9_DD2_0 (CPU_FTRS_POWER9 | CPU_FTR_P9_RADIX_PREFETCH_BUG)
+#define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | \
+                              CPU_FTR_P9_RADIX_PREFETCH_BUG | \
+                              CPU_FTR_POWER9_DD2_1)
 #define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
                               CPU_FTR_P9_TM_HV_ASSIST | \
                               CPU_FTR_P9_TM_XER_SO_BUG)
index 180b3a5d1001a46af83ea26ca7a8d686baf64f8b..182b4047c1ef978af1f998bf2a4f1dd88c419556 100644 (file)
@@ -727,17 +727,20 @@ static __init void cpufeatures_cpu_quirks(void)
        /*
         * Not all quirks can be derived from the cpufeatures device tree.
         */
-       if ((version & 0xffffefff) == 0x004e0200)
-               ; /* DD2.0 has no feature flag */
-       else if ((version & 0xffffefff) == 0x004e0201)
+       if ((version & 0xffffefff) == 0x004e0200) {
+               /* DD2.0 has no feature flag */
+               cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
+       } else if ((version & 0xffffefff) == 0x004e0201) {
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
-       else if ((version & 0xffffefff) == 0x004e0202) {
+               cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
+       } else if ((version & 0xffffefff) == 0x004e0202) {
                cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_HV_ASSIST;
                cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_XER_SO_BUG;
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
-       } else if ((version & 0xffff0000) == 0x004e0000)
+       } else if ((version & 0xffff0000) == 0x004e0000) {
                /* DD2.1 and up have DD2_1 */
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
+       }
 
        if ((version & 0xffff0000) == 0x004e0000) {
                cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
index c6fbbd29bd8717a44bcac3cc5706269867d9d272..dbc2fecc37f0564466c07b7aef52053b6fa25ab1 100644 (file)
@@ -1801,6 +1801,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        tlbsync
        ptesync
 
+BEGIN_FTR_SECTION
        /* Radix: Handle the case where the guest used an illegal PID */
        LOAD_REG_ADDR(r4, mmu_base_pid)
        lwz     r3, VCPU_GUEST_PID(r9)
@@ -1830,6 +1831,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        addi    r7,r7,0x1000
        bdnz    1b
        ptesync
+END_FTR_SECTION_IFSET(CPU_FTR_P9_RADIX_PREFETCH_BUG)
 
 2:
 #endif /* CONFIG_PPC_RADIX_MMU */
index 974109bb85dbc7b179a8d4d61ed629a77778ba06..dd1bea45325c6ed6ef707986efd0a21e58520222 100644 (file)
@@ -337,7 +337,11 @@ static void __init radix_init_pgtable(void)
        }
 
        /* Find out how many PID bits are supported */
-       if (cpu_has_feature(CPU_FTR_HVMODE)) {
+       if (!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
+               if (!mmu_pid_bits)
+                       mmu_pid_bits = 20;
+               mmu_base_pid = 1;
+       } else if (cpu_has_feature(CPU_FTR_HVMODE)) {
                if (!mmu_pid_bits)
                        mmu_pid_bits = 20;
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
index a95175c0972b7f16150ab1b88b9797d67c58084f..03f43c924e00943b5ef63c6bc6daab7a766157ae 100644 (file)
@@ -1161,6 +1161,9 @@ extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
        if (unlikely(pid == MMU_NO_CONTEXT))
                return;
 
+       if (!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG))
+               return;
+
        /*
         * If this context hasn't run on that CPU before and KVM is
         * around, there's a slim chance that the guest on another