powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9
authorNicholas Piggin <npiggin@gmail.com>
Mon, 27 Aug 2018 03:03:01 +0000 (13:03 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 4 Oct 2018 13:16:53 +0000 (23:16 +1000)
PPC_INVALIDATE_ERAT is slbia IH=7 which is a new variant introduced
with POWER9, and the result is undefined on earlier CPUs.

Commits 7b9f71f974 ("powerpc/64s: POWER9 machine check handler") and
d4748276ae ("powerpc/64s: Improve local TLB flush for boot and MCE on
POWER9") caused POWER7/8 code to use this instruction. Remove it. An
ERAT flush can be made by invalidatig the SLB, but before POWER9 that
requires a flush and rebolt.

Fixes: 7b9f71f974 ("powerpc/64s: POWER9 machine check handler")
Fixes: d4748276ae ("powerpc/64s: Improve local TLB flush for boot and MCE on POWER9")
Cc: stable@vger.kernel.org # v4.11+
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/mce_power.c
arch/powerpc/mm/hash_native_64.c

index 2016b58d564f0e58cfe1ffcb51a36b542ac815ad..6b800eec31f2fe16bda42e896e30eb3a2e31e6dd 100644 (file)
@@ -89,6 +89,13 @@ void flush_and_reload_slb(void)
 
 static void flush_erat(void)
 {
+#ifdef CONFIG_PPC_BOOK3S_64
+       if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
+               flush_and_reload_slb();
+               return;
+       }
+#endif
+       /* PPC_INVALIDATE_ERAT can only be used on ISA v3 and newer */
        asm volatile(PPC_INVALIDATE_ERAT : : :"memory");
 }
 
index 729f02df8290c4a9730d9b6af21abc0530c48072..aaa28fd918fe4ce26a5bb0a46909ecff9ec877c3 100644 (file)
@@ -115,6 +115,8 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is)
        tlbiel_hash_set_isa300(0, is, 0, 2, 1);
 
        asm volatile("ptesync": : :"memory");
+
+       asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
 }
 
 void hash__tlbiel_all(unsigned int action)
@@ -140,8 +142,6 @@ void hash__tlbiel_all(unsigned int action)
                tlbiel_all_isa206(POWER7_TLB_SETS, is);
        else
                WARN(1, "%s called on pre-POWER7 CPU\n", __func__);
-
-       asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory");
 }
 
 static inline unsigned long  ___tlbie(unsigned long vpn, int psize,