[PATCH 3/9] x86: Make old K8 swapgs workaround conditional

From: Andi Kleen
Date: Mon Mar 21 2016 - 12:16:21 EST


From: Andi Kleen <ak@xxxxxxxxxxxxxxx>

Every gs selector/index reload always paid an extra MFENCE
between the two SWAPGS. This was to work around an old
bug in early K8 steppings. All other CPUs don't need the extra
mfence. Patch the extra MFENCE only in for K8.

v2: Use set_cpu_bug()
v3: Use ALTERNATIVE directly
Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
---
arch/x86/entry/entry_64.S | 2 +-
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/kernel/cpu/amd.c | 3 +++
3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index c605710..252bce4 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -786,7 +786,7 @@ ENTRY(native_load_gs_index)
SWAPGS
gs_change:
movl %edi, %gs
-2: mfence /* workaround */
+2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_MFENCE
SWAPGS
popfq
ret
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 074b760..f3b3ff8 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -288,6 +288,7 @@
#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
+#define X86_BUG_SWAPGS_MFENCE X86_BUG(9) /* SWAPGS may need MFENCE */

#ifdef CONFIG_X86_32
/*
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 97c59fd..9cd932b 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -589,6 +589,9 @@ static void init_amd_k8(struct cpuinfo_x86 *c)
if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
set_cpu_cap(c, X86_FEATURE_REP_GOOD);

+ /* Early steppings needed a mfence on swapgs. */
+ set_cpu_bug(c, X86_BUG_SWAPGS_MFENCE);
+
/*
* Some BIOSes incorrectly force this feature, but only K8 revision D
* (model = 0x14) and later actually support it.
--
2.5.5