[PATCH 3/6] x86/mm/kaiser: Allow PCID with nokaiser

From: Peter Zijlstra
Date: Wed Nov 29 2017 - 05:38:29 EST


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

Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
---
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