Currently KAISER kills PCID on platforms that lack INVPCID, even when
nokaiser.

Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
---
 arch/x86/include/asm/tlbflush.h |    9 +++++----
 arch/x86/mm/init.c              |    2 +-
 arch/x86/mm/tlb.c               |    7 ++++++-
 3 files changed, 12 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -9,6 +9,7 @@
 #include <asm/cpufeature.h>
 #include <asm/special_insns.h>
 #include <asm/smp.h>
+#include <asm/kaiser.h>
 
 static inline void __invpcid(unsigned long pcid, unsigned long addr,
                             unsigned long type)
@@ -355,12 +356,12 @@ static inline void __native_flush_tlb(vo
                 * CR4 has X86_CR4_PCIDE set.  In other words, this does
                 * not fully flush the TLB if PCIDs are in use.
                 *
-                * With KAISER and PCIDs, the means that we did not
+                * With KAISER and PCIDs, that means that we did not
                 * flush the user PCID.  Warn if it gets called.
                 */
-               if (IS_ENABLED(CONFIG_KAISER))
-                       WARN_ON_ONCE(this_cpu_read(cpu_tlbstate.cr4) &
-                                    X86_CR4_PCIDE);
+               if (IS_ENABLED(CONFIG_KAISER) && kaiser_enabled)
+                       WARN_ON_ONCE(this_cpu_read(cpu_tlbstate.cr4) & 
X86_CR4_PCIDE);
+
                /*
                 * If current->mm == NULL then we borrow a mm
                 * which may change during a task switch and
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -219,7 +219,7 @@ static void setup_pcid(void)
                 * have KAISER and do not have INVPCID.
                 */
                if (!IS_ENABLED(CONFIG_X86_GLOBAL_PAGES) &&
-                   !boot_cpu_has(X86_FEATURE_INVPCID)) {
+                   kaiser_enabled && !boot_cpu_has(X86_FEATURE_INVPCID)) {
                        setup_clear_cpu_cap(X86_FEATURE_PCID);
                        return;
                }
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -6,13 +6,14 @@
 #include <linux/interrupt.h>
 #include <linux/export.h>
 #include <linux/cpu.h>
+#include <linux/debugfs.h>
 
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
 #include <asm/cache.h>
 #include <asm/apic.h>
 #include <asm/uv/uv.h>
-#include <linux/debugfs.h>
+#include <asm/kaiser.h>
 
 /*
  *     TLB flushing, formerly SMP-only
@@ -115,6 +116,10 @@ static void flush_user_asid(pgd_t *pgd,
         */
        if (!cpu_feature_enabled(X86_FEATURE_PCID))
                return;
+
+       if (!kaiser_enabled)
+               return;
+
        /*
         * With PCIDs enabled, write_cr3() only flushes TLB
         * entries for the current (kernel) ASID.  This leaves


Reply via email to