From: Andi Kleen <[email protected]>

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 <[email protected]>
---
 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

Reply via email to