Skip to content

Commit ab0f657

Browse files
bp3tk0vgregkh
authored andcommitted
x86/bugs: Add a Transient Scheduler Attacks mitigation
Commit d8010d4 upstream. Add the required features detection glue to bugs.c et all in order to support the TSA mitigation. Co-developed-by: Kim Phillips <[email protected]> Signed-off-by: Kim Phillips <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Pawan Gupta <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 27abf1d commit ab0f657

13 files changed

Lines changed: 229 additions & 6 deletions

File tree

Documentation/ABI/testing/sysfs-devices-system-cpu

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ What: /sys/devices/system/cpu/vulnerabilities
523523
/sys/devices/system/cpu/vulnerabilities/spectre_v1
524524
/sys/devices/system/cpu/vulnerabilities/spectre_v2
525525
/sys/devices/system/cpu/vulnerabilities/srbds
526+
/sys/devices/system/cpu/vulnerabilities/tsa
526527
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
527528
Date: January 2018
528529
Contact: Linux kernel mailing list <[email protected]>

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7423,6 +7423,19 @@
74237423
having this key zero'ed is acceptable. E.g. in testing
74247424
scenarios.
74257425

7426+
tsa= [X86] Control mitigation for Transient Scheduler
7427+
Attacks on AMD CPUs. Search the following in your
7428+
favourite search engine for more details:
7429+
7430+
"Technical guidance for mitigating transient scheduler
7431+
attacks".
7432+
7433+
off - disable the mitigation
7434+
on - enable the mitigation (default)
7435+
user - mitigate only user/kernel transitions
7436+
vm - mitigate only guest/host transitions
7437+
7438+
74267439
tsc= Disable clocksource stability checks for TSC.
74277440
Format: <string>
74287441
[x86] reliable: mark tsc clocksource as reliable, this

arch/x86/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2723,6 +2723,15 @@ config MITIGATION_ITS
27232723
disabled, mitigation cannot be enabled via cmdline.
27242724
See <file:Documentation/admin-guide/hw-vuln/indirect-target-selection.rst>
27252725

2726+
config MITIGATION_TSA
2727+
bool "Mitigate Transient Scheduler Attacks"
2728+
depends on CPU_SUP_AMD
2729+
default y
2730+
help
2731+
Enable mitigation for Transient Scheduler Attacks. TSA is a hardware
2732+
security vulnerability on AMD CPUs which can lead to forwarding of
2733+
invalid info to subsequent instructions and thus can affect their
2734+
timing and thereby cause a leakage.
27262735
endif
27272736

27282737
config ARCH_HAS_ADD_PAGES

arch/x86/include/asm/cpufeatures.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@
453453
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */
454454
#define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */
455455
#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */
456+
#define X86_FEATURE_VERW_CLEAR (20*32+ 5) /* The memory form of VERW mitigates TSA */
456457
#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */
457458
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */
458459
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */
@@ -482,6 +483,9 @@
482483
#define X86_FEATURE_AMD_WORKLOAD_CLASS (21*32 + 7) /* Workload Classification */
483484
#define X86_FEATURE_PREFER_YMM (21*32 + 8) /* Avoid ZMM registers due to downclocking */
484485
#define X86_FEATURE_INDIRECT_THUNK_ITS (21*32 + 9) /* Use thunk for indirect branches in lower half of cacheline */
486+
#define X86_FEATURE_TSA_SQ_NO (21*32+11) /* AMD CPU not vulnerable to TSA-SQ */
487+
#define X86_FEATURE_TSA_L1_NO (21*32+12) /* AMD CPU not vulnerable to TSA-L1 */
488+
#define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* Clear CPU buffers using VERW before VMRUN */
485489

486490
/*
487491
* BUG word(s)
@@ -536,4 +540,5 @@
536540
#define X86_BUG_SPECTRE_V2_USER X86_BUG(1*32 + 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */
537541
#define X86_BUG_ITS X86_BUG(1*32 + 6) /* "its" CPU is affected by Indirect Target Selection */
538542
#define X86_BUG_ITS_NATIVE_ONLY X86_BUG(1*32 + 7) /* "its_native_only" CPU is affected by ITS, VMX is not affected */
543+
#define X86_BUG_TSA X86_BUG( 1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */
539544
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/include/asm/mwait.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static __always_inline void __mwait(unsigned long eax, unsigned long ecx)
7979
static __always_inline void __mwaitx(unsigned long eax, unsigned long ebx,
8080
unsigned long ecx)
8181
{
82-
/* No MDS buffer clear as this is AMD/HYGON only */
82+
/* No need for TSA buffer clearing on AMD */
8383

8484
/* "mwaitx %eax, %ebx, %ecx;" */
8585
asm volatile(".byte 0x0f, 0x01, 0xfb;"

arch/x86/include/asm/nospec-branch.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,19 +308,25 @@
308308
* CFLAGS.ZF.
309309
* Note: Only the memory operand variant of VERW clears the CPU buffers.
310310
*/
311-
.macro CLEAR_CPU_BUFFERS
311+
.macro __CLEAR_CPU_BUFFERS feature
312312
#ifdef CONFIG_X86_64
313-
ALTERNATIVE "", "verw x86_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF
313+
ALTERNATIVE "", "verw x86_verw_sel(%rip)", \feature
314314
#else
315315
/*
316316
* In 32bit mode, the memory operand must be a %cs reference. The data
317317
* segments may not be usable (vm86 mode), and the stack segment may not
318318
* be flat (ESPFIX32).
319319
*/
320-
ALTERNATIVE "", "verw %cs:x86_verw_sel", X86_FEATURE_CLEAR_CPU_BUF
320+
ALTERNATIVE "", "verw %cs:x86_verw_sel", \feature
321321
#endif
322322
.endm
323323

324+
#define CLEAR_CPU_BUFFERS \
325+
__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF
326+
327+
#define VM_CLEAR_CPU_BUFFERS \
328+
__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF_VM
329+
324330
#ifdef CONFIG_X86_64
325331
.macro CLEAR_BRANCH_HISTORY
326332
ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP
@@ -602,7 +608,7 @@ static __always_inline void x86_clear_cpu_buffers(void)
602608

603609
/**
604610
* x86_idle_clear_cpu_buffers - Buffer clearing support in idle for the MDS
605-
* vulnerability
611+
* and TSA vulnerabilities.
606612
*
607613
* Clear CPU buffers if the corresponding static key is enabled
608614
*/

arch/x86/kernel/cpu/amd.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,47 @@ static void bsp_determine_snp(struct cpuinfo_x86 *c)
375375
#endif
376376
}
377377

378+
#define ZEN_MODEL_STEP_UCODE(fam, model, step, ucode) \
379+
X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, fam, model), \
380+
step, step, ucode)
381+
382+
static const struct x86_cpu_id amd_tsa_microcode[] = {
383+
ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x1, 0x0a0011d7),
384+
ZEN_MODEL_STEP_UCODE(0x19, 0x01, 0x2, 0x0a00123b),
385+
ZEN_MODEL_STEP_UCODE(0x19, 0x08, 0x2, 0x0a00820d),
386+
ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x1, 0x0a10114c),
387+
ZEN_MODEL_STEP_UCODE(0x19, 0x11, 0x2, 0x0a10124c),
388+
ZEN_MODEL_STEP_UCODE(0x19, 0x18, 0x1, 0x0a108109),
389+
ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x0, 0x0a20102e),
390+
ZEN_MODEL_STEP_UCODE(0x19, 0x21, 0x2, 0x0a201211),
391+
ZEN_MODEL_STEP_UCODE(0x19, 0x44, 0x1, 0x0a404108),
392+
ZEN_MODEL_STEP_UCODE(0x19, 0x50, 0x0, 0x0a500012),
393+
ZEN_MODEL_STEP_UCODE(0x19, 0x61, 0x2, 0x0a60120a),
394+
ZEN_MODEL_STEP_UCODE(0x19, 0x74, 0x1, 0x0a704108),
395+
ZEN_MODEL_STEP_UCODE(0x19, 0x75, 0x2, 0x0a705208),
396+
ZEN_MODEL_STEP_UCODE(0x19, 0x78, 0x0, 0x0a708008),
397+
ZEN_MODEL_STEP_UCODE(0x19, 0x7c, 0x0, 0x0a70c008),
398+
ZEN_MODEL_STEP_UCODE(0x19, 0xa0, 0x2, 0x0aa00216),
399+
{},
400+
};
401+
402+
static void tsa_init(struct cpuinfo_x86 *c)
403+
{
404+
if (cpu_has(c, X86_FEATURE_HYPERVISOR))
405+
return;
406+
407+
if (cpu_has(c, X86_FEATURE_ZEN3) ||
408+
cpu_has(c, X86_FEATURE_ZEN4)) {
409+
if (x86_match_min_microcode_rev(amd_tsa_microcode))
410+
setup_force_cpu_cap(X86_FEATURE_VERW_CLEAR);
411+
else
412+
pr_debug("%s: current revision: 0x%x\n", __func__, c->microcode);
413+
} else {
414+
setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO);
415+
setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO);
416+
}
417+
}
418+
378419
static void bsp_init_amd(struct cpuinfo_x86 *c)
379420
{
380421
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
@@ -487,6 +528,9 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
487528
}
488529

489530
bsp_determine_snp(c);
531+
532+
tsa_init(c);
533+
490534
return;
491535

492536
warn:

arch/x86/kernel/cpu/bugs.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ static void __init l1d_flush_select_mitigation(void);
5050
static void __init srso_select_mitigation(void);
5151
static void __init gds_select_mitigation(void);
5252
static void __init its_select_mitigation(void);
53+
static void __init tsa_select_mitigation(void);
5354

5455
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
5556
u64 x86_spec_ctrl_base;
@@ -188,6 +189,7 @@ void __init cpu_select_mitigations(void)
188189
srso_select_mitigation();
189190
gds_select_mitigation();
190191
its_select_mitigation();
192+
tsa_select_mitigation();
191193
}
192194

193195
/*
@@ -2074,6 +2076,94 @@ static void update_mds_branch_idle(void)
20742076
#define TAA_MSG_SMT "TAA CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/tsx_async_abort.html for more details.\n"
20752077
#define MMIO_MSG_SMT "MMIO Stale Data CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/processor_mmio_stale_data.html for more details.\n"
20762078

2079+
#undef pr_fmt
2080+
#define pr_fmt(fmt) "Transient Scheduler Attacks: " fmt
2081+
2082+
enum tsa_mitigations {
2083+
TSA_MITIGATION_NONE,
2084+
TSA_MITIGATION_UCODE_NEEDED,
2085+
TSA_MITIGATION_USER_KERNEL,
2086+
TSA_MITIGATION_VM,
2087+
TSA_MITIGATION_FULL,
2088+
};
2089+
2090+
static const char * const tsa_strings[] = {
2091+
[TSA_MITIGATION_NONE] = "Vulnerable",
2092+
[TSA_MITIGATION_UCODE_NEEDED] = "Vulnerable: Clear CPU buffers attempted, no microcode",
2093+
[TSA_MITIGATION_USER_KERNEL] = "Mitigation: Clear CPU buffers: user/kernel boundary",
2094+
[TSA_MITIGATION_VM] = "Mitigation: Clear CPU buffers: VM",
2095+
[TSA_MITIGATION_FULL] = "Mitigation: Clear CPU buffers",
2096+
};
2097+
2098+
static enum tsa_mitigations tsa_mitigation __ro_after_init =
2099+
IS_ENABLED(CONFIG_MITIGATION_TSA) ? TSA_MITIGATION_FULL : TSA_MITIGATION_NONE;
2100+
2101+
static int __init tsa_parse_cmdline(char *str)
2102+
{
2103+
if (!str)
2104+
return -EINVAL;
2105+
2106+
if (!strcmp(str, "off"))
2107+
tsa_mitigation = TSA_MITIGATION_NONE;
2108+
else if (!strcmp(str, "on"))
2109+
tsa_mitigation = TSA_MITIGATION_FULL;
2110+
else if (!strcmp(str, "user"))
2111+
tsa_mitigation = TSA_MITIGATION_USER_KERNEL;
2112+
else if (!strcmp(str, "vm"))
2113+
tsa_mitigation = TSA_MITIGATION_VM;
2114+
else
2115+
pr_err("Ignoring unknown tsa=%s option.\n", str);
2116+
2117+
return 0;
2118+
}
2119+
early_param("tsa", tsa_parse_cmdline);
2120+
2121+
static void __init tsa_select_mitigation(void)
2122+
{
2123+
if (tsa_mitigation == TSA_MITIGATION_NONE)
2124+
return;
2125+
2126+
if (cpu_mitigations_off() || !boot_cpu_has_bug(X86_BUG_TSA)) {
2127+
tsa_mitigation = TSA_MITIGATION_NONE;
2128+
return;
2129+
}
2130+
2131+
if (!boot_cpu_has(X86_FEATURE_VERW_CLEAR))
2132+
tsa_mitigation = TSA_MITIGATION_UCODE_NEEDED;
2133+
2134+
switch (tsa_mitigation) {
2135+
case TSA_MITIGATION_USER_KERNEL:
2136+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
2137+
break;
2138+
2139+
case TSA_MITIGATION_VM:
2140+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
2141+
break;
2142+
2143+
case TSA_MITIGATION_UCODE_NEEDED:
2144+
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
2145+
goto out;
2146+
2147+
pr_notice("Forcing mitigation on in a VM\n");
2148+
2149+
/*
2150+
* On the off-chance that microcode has been updated
2151+
* on the host, enable the mitigation in the guest just
2152+
* in case.
2153+
*/
2154+
fallthrough;
2155+
case TSA_MITIGATION_FULL:
2156+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
2157+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
2158+
break;
2159+
default:
2160+
break;
2161+
}
2162+
2163+
out:
2164+
pr_info("%s\n", tsa_strings[tsa_mitigation]);
2165+
}
2166+
20772167
void cpu_bugs_smt_update(void)
20782168
{
20792169
mutex_lock(&spec_ctrl_mutex);
@@ -2130,6 +2220,24 @@ void cpu_bugs_smt_update(void)
21302220
break;
21312221
}
21322222

2223+
switch (tsa_mitigation) {
2224+
case TSA_MITIGATION_USER_KERNEL:
2225+
case TSA_MITIGATION_VM:
2226+
case TSA_MITIGATION_FULL:
2227+
case TSA_MITIGATION_UCODE_NEEDED:
2228+
/*
2229+
* TSA-SQ can potentially lead to info leakage between
2230+
* SMT threads.
2231+
*/
2232+
if (sched_smt_active())
2233+
static_branch_enable(&cpu_buf_idle_clear);
2234+
else
2235+
static_branch_disable(&cpu_buf_idle_clear);
2236+
break;
2237+
case TSA_MITIGATION_NONE:
2238+
break;
2239+
}
2240+
21332241
mutex_unlock(&spec_ctrl_mutex);
21342242
}
21352243

@@ -3078,6 +3186,11 @@ static ssize_t gds_show_state(char *buf)
30783186
return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]);
30793187
}
30803188

3189+
static ssize_t tsa_show_state(char *buf)
3190+
{
3191+
return sysfs_emit(buf, "%s\n", tsa_strings[tsa_mitigation]);
3192+
}
3193+
30813194
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
30823195
char *buf, unsigned int bug)
30833196
{
@@ -3139,6 +3252,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
31393252
case X86_BUG_ITS:
31403253
return its_show_state(buf);
31413254

3255+
case X86_BUG_TSA:
3256+
return tsa_show_state(buf);
3257+
31423258
default:
31433259
break;
31443260
}
@@ -3223,6 +3339,11 @@ ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_att
32233339
{
32243340
return cpu_show_common(dev, attr, buf, X86_BUG_ITS);
32253341
}
3342+
3343+
ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *buf)
3344+
{
3345+
return cpu_show_common(dev, attr, buf, X86_BUG_TSA);
3346+
}
32263347
#endif
32273348

32283349
void __warn_thunk(void)

arch/x86/kernel/cpu/common.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
12321232
#define ITS BIT(8)
12331233
/* CPU is affected by Indirect Target Selection, but guest-host isolation is not affected */
12341234
#define ITS_NATIVE_ONLY BIT(9)
1235+
/* CPU is affected by Transient Scheduler Attacks */
1236+
#define TSA BIT(10)
12351237

12361238
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12371239
VULNBL_INTEL_STEPS(INTEL_IVYBRIDGE, X86_STEP_MAX, SRBDS),
@@ -1279,7 +1281,7 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12791281
VULNBL_AMD(0x16, RETBLEED),
12801282
VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO),
12811283
VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO),
1282-
VULNBL_AMD(0x19, SRSO),
1284+
VULNBL_AMD(0x19, SRSO | TSA),
12831285
VULNBL_AMD(0x1a, SRSO),
12841286
{}
12851287
};
@@ -1492,6 +1494,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
14921494
setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY);
14931495
}
14941496

1497+
if (c->x86_vendor == X86_VENDOR_AMD) {
1498+
if (!cpu_has(c, X86_FEATURE_TSA_SQ_NO) ||
1499+
!cpu_has(c, X86_FEATURE_TSA_L1_NO)) {
1500+
if (cpu_matches(cpu_vuln_blacklist, TSA) ||
1501+
/* Enable bug on Zen guests to allow for live migration. */
1502+
(cpu_has(c, X86_FEATURE_HYPERVISOR) && cpu_has(c, X86_FEATURE_ZEN)))
1503+
setup_force_cpu_bug(X86_BUG_TSA);
1504+
}
1505+
}
1506+
14951507
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
14961508
return;
14971509

arch/x86/kernel/cpu/scattered.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static const struct cpuid_bit cpuid_bits[] = {
4949
{ X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 },
5050
{ X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 },
5151
{ X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
52+
{ X86_FEATURE_TSA_SQ_NO, CPUID_ECX, 1, 0x80000021, 0 },
53+
{ X86_FEATURE_TSA_L1_NO, CPUID_ECX, 2, 0x80000021, 0 },
5254
{ X86_FEATURE_AMD_WORKLOAD_CLASS, CPUID_EAX, 22, 0x80000021, 0 },
5355
{ X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 },
5456
{ X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 },

0 commit comments

Comments
 (0)