Skip to content

Commit f5d2799

Browse files
KAGA-KOKOshiloong
authored andcommitted
x86/speculation/swapgs: Exclude ATOMs from speculation through SWAPGS
commit f36cf38 upstream. Intel provided the following information: On all current Atom processors, instructions that use a segment register value (e.g. a load or store) will not speculatively execute before the last writer of that segment retires. Thus they will not use a speculatively written segment value. That means on ATOMs there is no speculation through SWAPGS, so the SWAPGS entry paths can be excluded from the extra LFENCE if PTI is disabled. Create a separate bug flag for the through SWAPGS speculation and mark all out-of-order ATOMs and AMD/HYGON CPUs as not affected. The in-order ATOMs are excluded from the whole mitigation mess anyway. Reported-by: Andrew Cooper <andrew.cooper3@citrix.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Tyler Hicks <tyhicks@canonical.com> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Shile Zhang <shile.zhang@linux.alibaba.com> Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
1 parent 49e1ce9 commit f5d2799

File tree

3 files changed

+32
-29
lines changed

3 files changed

+32
-29
lines changed

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,5 +386,6 @@
386386
#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
387387
#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
388388
#define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */
389+
#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
389390

390391
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/kernel/cpu/bugs.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -282,18 +282,6 @@ static const char * const spectre_v1_strings[] = {
282282
[SPECTRE_V1_MITIGATION_AUTO] = "Mitigation: usercopy/swapgs barriers and __user pointer sanitization",
283283
};
284284

285-
static bool is_swapgs_serializing(void)
286-
{
287-
/*
288-
* Technically, swapgs isn't serializing on AMD (despite it previously
289-
* being documented as such in the APM). But according to AMD, %gs is
290-
* updated non-speculatively, and the issuing of %gs-relative memory
291-
* operands will be blocked until the %gs update completes, which is
292-
* good enough for our purposes.
293-
*/
294-
return boot_cpu_data.x86_vendor == X86_VENDOR_AMD;
295-
}
296-
297285
/*
298286
* Does SMAP provide full mitigation against speculative kernel access to
299287
* userspace?
@@ -344,9 +332,11 @@ static void __init spectre_v1_select_mitigation(void)
344332
* PTI as the CR3 write in the Meltdown mitigation
345333
* is serializing.
346334
*
347-
* If neither is there, mitigate with an LFENCE.
335+
* If neither is there, mitigate with an LFENCE to
336+
* stop speculation through swapgs.
348337
*/
349-
if (!is_swapgs_serializing() && !boot_cpu_has(X86_FEATURE_PTI))
338+
if (boot_cpu_has_bug(X86_BUG_SWAPGS) &&
339+
!boot_cpu_has(X86_FEATURE_PTI))
350340
setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_USER);
351341

352342
/*

arch/x86/kernel/cpu/common.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
952952
#define NO_L1TF BIT(3)
953953
#define NO_MDS BIT(4)
954954
#define MSBDS_ONLY BIT(5)
955+
#define NO_SWAPGS BIT(6)
955956

956957
#define VULNWL(_vendor, _family, _model, _whitelist) \
957958
{ X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
@@ -975,29 +976,37 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
975976
VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION),
976977
VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION),
977978

978-
VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
979-
VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY),
980-
VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY),
981-
VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
982-
VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY),
983-
VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY),
979+
VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
980+
VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
981+
VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
982+
VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
983+
VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
984+
VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
984985

985986
VULNWL_INTEL(CORE_YONAH, NO_SSB),
986987

987-
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY),
988+
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
988989

989-
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
990-
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
991-
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
990+
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS),
991+
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS),
992+
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS),
993+
994+
/*
995+
* Technically, swapgs isn't serializing on AMD (despite it previously
996+
* being documented as such in the APM). But according to AMD, %gs is
997+
* updated non-speculatively, and the issuing of %gs-relative memory
998+
* operands will be blocked until the %gs update completes, which is
999+
* good enough for our purposes.
1000+
*/
9921001

9931002
/* AMD Family 0xf - 0x12 */
994-
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
995-
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
996-
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
997-
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
1003+
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
1004+
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
1005+
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
1006+
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
9981007

9991008
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
1000-
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
1009+
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS),
10011010
{}
10021011
};
10031012

@@ -1034,6 +1043,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
10341043
setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
10351044
}
10361045

1046+
if (!cpu_matches(NO_SWAPGS))
1047+
setup_force_cpu_bug(X86_BUG_SWAPGS);
1048+
10371049
if (cpu_matches(NO_MELTDOWN))
10381050
return;
10391051

0 commit comments

Comments
 (0)