Skip to content

Commit d12145e

Browse files
bp3tk0vgregkh
authored andcommitted
x86/bugs: Add a Transient Scheduler Attacks mitigation
commit d8010d4ba43e9f790925375a7de100604a5e2dba 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 3893cd0 commit d12145e

File tree

14 files changed

+259
-5
lines changed

14 files changed

+259
-5
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ What: /sys/devices/system/cpu/vulnerabilities
526526
/sys/devices/system/cpu/vulnerabilities/spectre_v1
527527
/sys/devices/system/cpu/vulnerabilities/spectre_v2
528528
/sys/devices/system/cpu/vulnerabilities/srbds
529+
/sys/devices/system/cpu/vulnerabilities/tsa
529530
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
530531
Date: January 2018
531532
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
@@ -6400,6 +6400,19 @@
64006400
If not specified, "default" is used. In this case,
64016401
the RNG's choice is left to each individual trust source.
64026402

6403+
tsa= [X86] Control mitigation for Transient Scheduler
6404+
Attacks on AMD CPUs. Search the following in your
6405+
favourite search engine for more details:
6406+
6407+
"Technical guidance for mitigating transient scheduler
6408+
attacks".
6409+
6410+
off - disable the mitigation
6411+
on - enable the mitigation (default)
6412+
user - mitigate only user/kernel transitions
6413+
vm - mitigate only guest/host transitions
6414+
6415+
64036416
tsc= Disable clocksource stability checks for TSC.
64046417
Format: <string>
64056418
[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
@@ -2586,6 +2586,15 @@ config MITIGATION_ITS
25862586
disabled, mitigation cannot be enabled via cmdline.
25872587
See <file:Documentation/admin-guide/hw-vuln/indirect-target-selection.rst>
25882588

2589+
config MITIGATION_TSA
2590+
bool "Mitigate Transient Scheduler Attacks"
2591+
depends on CPU_SUP_AMD
2592+
default y
2593+
help
2594+
Enable mitigation for Transient Scheduler Attacks. TSA is a hardware
2595+
security vulnerability on AMD CPUs which can lead to forwarding of
2596+
invalid info to subsequent instructions and thus can affect their
2597+
timing and thereby cause a leakage.
25892598
endif
25902599

25912600
config ARCH_HAS_ADD_PAGES

arch/x86/include/asm/cpu.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,16 @@ extern u64 x86_read_arch_cap_msr(void);
9898

9999
extern struct cpumask cpus_stop_mask;
100100

101+
union zen_patch_rev {
102+
struct {
103+
__u32 rev : 8,
104+
stepping : 4,
105+
model : 4,
106+
__reserved : 4,
107+
ext_model : 4,
108+
ext_fam : 8;
109+
};
110+
__u32 ucode_rev;
111+
};
112+
101113
#endif /* _ASM_X86_CPU_H */

arch/x86/include/asm/cpufeatures.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@
430430
#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */
431431

432432
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */
433+
#define X86_FEATURE_VERW_CLEAR (20*32+ 10) /* "" The memory form of VERW mitigates TSA */
433434
#define X86_FEATURE_SBPB (20*32+27) /* "" Selective Branch Prediction Barrier */
434435
#define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* "" MSR_PRED_CMD[IBPB] flushes all branch type predictions */
435436
#define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */
@@ -447,6 +448,10 @@
447448
#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */
448449
#define X86_FEATURE_INDIRECT_THUNK_ITS (21*32 + 5) /* "" Use thunk for indirect branches in lower half of cacheline */
449450

451+
#define X86_FEATURE_TSA_SQ_NO (21*32+11) /* "" AMD CPU not vulnerable to TSA-SQ */
452+
#define X86_FEATURE_TSA_L1_NO (21*32+12) /* "" AMD CPU not vulnerable to TSA-L1 */
453+
#define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* "" Clear CPU buffers using VERW before VMRUN */
454+
450455
/*
451456
* BUG word(s)
452457
*/
@@ -498,4 +503,5 @@
498503
#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
499504
#define X86_BUG_ITS X86_BUG(1*32 + 5) /* CPU is affected by Indirect Target Selection */
500505
#define X86_BUG_ITS_NATIVE_ONLY X86_BUG(1*32 + 6) /* CPU is affected by ITS, VMX is not affected */
506+
#define X86_BUG_TSA X86_BUG(1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */
501507
#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
@@ -80,7 +80,7 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
8080
static inline void __mwaitx(unsigned long eax, unsigned long ebx,
8181
unsigned long ecx)
8282
{
83-
/* No MDS buffer clear as this is AMD/HYGON only */
83+
/* No need for TSA buffer clearing on AMD */
8484

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

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,8 @@
208208
* CFLAGS.ZF.
209209
* Note: Only the memory operand variant of VERW clears the CPU buffers.
210210
*/
211-
.macro CLEAR_CPU_BUFFERS
212-
ALTERNATIVE "jmp .Lskip_verw_\@", "", X86_FEATURE_CLEAR_CPU_BUF
211+
.macro __CLEAR_CPU_BUFFERS feature
212+
ALTERNATIVE "jmp .Lskip_verw_\@", "", \feature
213213
#ifdef CONFIG_X86_64
214214
verw x86_verw_sel(%rip)
215215
#else
@@ -223,6 +223,12 @@
223223
.Lskip_verw_\@:
224224
.endm
225225

226+
#define CLEAR_CPU_BUFFERS \
227+
__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF
228+
229+
#define VM_CLEAR_CPU_BUFFERS \
230+
__CLEAR_CPU_BUFFERS X86_FEATURE_CLEAR_CPU_BUF_VM
231+
226232
#ifdef CONFIG_X86_64
227233
.macro CLEAR_BRANCH_HISTORY
228234
ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP
@@ -462,7 +468,7 @@ static __always_inline void x86_clear_cpu_buffers(void)
462468

463469
/**
464470
* x86_idle_clear_cpu_buffers - Buffer clearing support in idle for the MDS
465-
* vulnerability
471+
* and TSA vulnerabilities.
466472
*
467473
* Clear CPU buffers if the corresponding static key is enabled
468474
*/

arch/x86/kernel/cpu/amd.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,61 @@ static void early_init_amd_mc(struct cpuinfo_x86 *c)
553553
#endif
554554
}
555555

556+
static bool amd_check_tsa_microcode(void)
557+
{
558+
struct cpuinfo_x86 *c = &boot_cpu_data;
559+
union zen_patch_rev p;
560+
u32 min_rev = 0;
561+
562+
p.ext_fam = c->x86 - 0xf;
563+
p.model = c->x86_model;
564+
p.stepping = c->x86_stepping;
565+
566+
if (c->x86 == 0x19) {
567+
switch (p.ucode_rev >> 8) {
568+
case 0xa0011: min_rev = 0x0a0011d7; break;
569+
case 0xa0012: min_rev = 0x0a00123b; break;
570+
case 0xa0082: min_rev = 0x0a00820d; break;
571+
case 0xa1011: min_rev = 0x0a10114c; break;
572+
case 0xa1012: min_rev = 0x0a10124c; break;
573+
case 0xa1081: min_rev = 0x0a108109; break;
574+
case 0xa2010: min_rev = 0x0a20102e; break;
575+
case 0xa2012: min_rev = 0x0a201211; break;
576+
case 0xa4041: min_rev = 0x0a404108; break;
577+
case 0xa5000: min_rev = 0x0a500012; break;
578+
case 0xa6012: min_rev = 0x0a60120a; break;
579+
case 0xa7041: min_rev = 0x0a704108; break;
580+
case 0xa7052: min_rev = 0x0a705208; break;
581+
case 0xa7080: min_rev = 0x0a708008; break;
582+
case 0xa70c0: min_rev = 0x0a70c008; break;
583+
case 0xaa002: min_rev = 0x0aa00216; break;
584+
default:
585+
pr_debug("%s: ucode_rev: 0x%x, current revision: 0x%x\n",
586+
__func__, p.ucode_rev, c->microcode);
587+
return false;
588+
}
589+
}
590+
591+
if (!min_rev)
592+
return false;
593+
594+
return c->microcode >= min_rev;
595+
}
596+
597+
static void tsa_init(struct cpuinfo_x86 *c)
598+
{
599+
if (cpu_has(c, X86_FEATURE_HYPERVISOR))
600+
return;
601+
602+
if (c->x86 == 0x19) {
603+
if (amd_check_tsa_microcode())
604+
setup_force_cpu_cap(X86_FEATURE_VERW_CLEAR);
605+
} else {
606+
setup_force_cpu_cap(X86_FEATURE_TSA_SQ_NO);
607+
setup_force_cpu_cap(X86_FEATURE_TSA_L1_NO);
608+
}
609+
}
610+
556611
static void bsp_init_amd(struct cpuinfo_x86 *c)
557612
{
558613
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
@@ -663,6 +718,9 @@ static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)
663718
if (!(msr & MSR_K7_HWCR_SMMLOCK))
664719
goto clear_sev;
665720

721+
722+
tsa_init(c);
723+
666724
return;
667725

668726
clear_all:

arch/x86/kernel/cpu/bugs.c

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

5354
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
5455
u64 x86_spec_ctrl_base;
@@ -184,6 +185,7 @@ void __init cpu_select_mitigations(void)
184185
srso_select_mitigation();
185186
gds_select_mitigation();
186187
its_select_mitigation();
188+
tsa_select_mitigation();
187189
}
188190

189191
/*
@@ -2039,6 +2041,94 @@ static void update_mds_branch_idle(void)
20392041
#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"
20402042
#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"
20412043

2044+
#undef pr_fmt
2045+
#define pr_fmt(fmt) "Transient Scheduler Attacks: " fmt
2046+
2047+
enum tsa_mitigations {
2048+
TSA_MITIGATION_NONE,
2049+
TSA_MITIGATION_UCODE_NEEDED,
2050+
TSA_MITIGATION_USER_KERNEL,
2051+
TSA_MITIGATION_VM,
2052+
TSA_MITIGATION_FULL,
2053+
};
2054+
2055+
static const char * const tsa_strings[] = {
2056+
[TSA_MITIGATION_NONE] = "Vulnerable",
2057+
[TSA_MITIGATION_UCODE_NEEDED] = "Vulnerable: Clear CPU buffers attempted, no microcode",
2058+
[TSA_MITIGATION_USER_KERNEL] = "Mitigation: Clear CPU buffers: user/kernel boundary",
2059+
[TSA_MITIGATION_VM] = "Mitigation: Clear CPU buffers: VM",
2060+
[TSA_MITIGATION_FULL] = "Mitigation: Clear CPU buffers",
2061+
};
2062+
2063+
static enum tsa_mitigations tsa_mitigation __ro_after_init =
2064+
IS_ENABLED(CONFIG_MITIGATION_TSA) ? TSA_MITIGATION_FULL : TSA_MITIGATION_NONE;
2065+
2066+
static int __init tsa_parse_cmdline(char *str)
2067+
{
2068+
if (!str)
2069+
return -EINVAL;
2070+
2071+
if (!strcmp(str, "off"))
2072+
tsa_mitigation = TSA_MITIGATION_NONE;
2073+
else if (!strcmp(str, "on"))
2074+
tsa_mitigation = TSA_MITIGATION_FULL;
2075+
else if (!strcmp(str, "user"))
2076+
tsa_mitigation = TSA_MITIGATION_USER_KERNEL;
2077+
else if (!strcmp(str, "vm"))
2078+
tsa_mitigation = TSA_MITIGATION_VM;
2079+
else
2080+
pr_err("Ignoring unknown tsa=%s option.\n", str);
2081+
2082+
return 0;
2083+
}
2084+
early_param("tsa", tsa_parse_cmdline);
2085+
2086+
static void __init tsa_select_mitigation(void)
2087+
{
2088+
if (tsa_mitigation == TSA_MITIGATION_NONE)
2089+
return;
2090+
2091+
if (cpu_mitigations_off() || !boot_cpu_has_bug(X86_BUG_TSA)) {
2092+
tsa_mitigation = TSA_MITIGATION_NONE;
2093+
return;
2094+
}
2095+
2096+
if (!boot_cpu_has(X86_FEATURE_VERW_CLEAR))
2097+
tsa_mitigation = TSA_MITIGATION_UCODE_NEEDED;
2098+
2099+
switch (tsa_mitigation) {
2100+
case TSA_MITIGATION_USER_KERNEL:
2101+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
2102+
break;
2103+
2104+
case TSA_MITIGATION_VM:
2105+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
2106+
break;
2107+
2108+
case TSA_MITIGATION_UCODE_NEEDED:
2109+
if (!boot_cpu_has(X86_FEATURE_HYPERVISOR))
2110+
goto out;
2111+
2112+
pr_notice("Forcing mitigation on in a VM\n");
2113+
2114+
/*
2115+
* On the off-chance that microcode has been updated
2116+
* on the host, enable the mitigation in the guest just
2117+
* in case.
2118+
*/
2119+
fallthrough;
2120+
case TSA_MITIGATION_FULL:
2121+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
2122+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);
2123+
break;
2124+
default:
2125+
break;
2126+
}
2127+
2128+
out:
2129+
pr_info("%s\n", tsa_strings[tsa_mitigation]);
2130+
}
2131+
20422132
void cpu_bugs_smt_update(void)
20432133
{
20442134
mutex_lock(&spec_ctrl_mutex);
@@ -2092,6 +2182,24 @@ void cpu_bugs_smt_update(void)
20922182
break;
20932183
}
20942184

2185+
switch (tsa_mitigation) {
2186+
case TSA_MITIGATION_USER_KERNEL:
2187+
case TSA_MITIGATION_VM:
2188+
case TSA_MITIGATION_FULL:
2189+
case TSA_MITIGATION_UCODE_NEEDED:
2190+
/*
2191+
* TSA-SQ can potentially lead to info leakage between
2192+
* SMT threads.
2193+
*/
2194+
if (sched_smt_active())
2195+
static_branch_enable(&cpu_buf_idle_clear);
2196+
else
2197+
static_branch_disable(&cpu_buf_idle_clear);
2198+
break;
2199+
case TSA_MITIGATION_NONE:
2200+
break;
2201+
}
2202+
20952203
mutex_unlock(&spec_ctrl_mutex);
20962204
}
20972205

@@ -3026,6 +3134,11 @@ static ssize_t srso_show_state(char *buf)
30263134
boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode");
30273135
}
30283136

3137+
static ssize_t tsa_show_state(char *buf)
3138+
{
3139+
return sysfs_emit(buf, "%s\n", tsa_strings[tsa_mitigation]);
3140+
}
3141+
30293142
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
30303143
char *buf, unsigned int bug)
30313144
{
@@ -3087,6 +3200,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
30873200
case X86_BUG_ITS:
30883201
return its_show_state(buf);
30893202

3203+
case X86_BUG_TSA:
3204+
return tsa_show_state(buf);
3205+
30903206
default:
30913207
break;
30923208
}
@@ -3171,4 +3287,9 @@ ssize_t cpu_show_indirect_target_selection(struct device *dev, struct device_att
31713287
{
31723288
return cpu_show_common(dev, attr, buf, X86_BUG_ITS);
31733289
}
3290+
3291+
ssize_t cpu_show_tsa(struct device *dev, struct device_attribute *attr, char *buf)
3292+
{
3293+
return cpu_show_common(dev, attr, buf, X86_BUG_TSA);
3294+
}
31743295
#endif

0 commit comments

Comments
 (0)