Skip to content

Commit 6e9128f

Browse files
committed
Merge tag 'tsa_x86_bugs_for_6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull CPU speculation fixes from Borislav Petkov: "Add the mitigation logic for Transient Scheduler Attacks (TSA) TSA are new aspeculative side channel attacks related to the execution timing of instructions under specific microarchitectural conditions. In some cases, an attacker may be able to use this timing information to infer data from other contexts, resulting in information leakage. Add the usual controls of the mitigation and integrate it into the existing speculation bugs infrastructure in the kernel" * tag 'tsa_x86_bugs_for_6.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/process: Move the buffer clearing before MONITOR x86/microcode/AMD: Add TSA microcode SHAs KVM: SVM: Advertise TSA CPUID bits to guests x86/bugs: Add a Transient Scheduler Attacks mitigation x86/bugs: Rename MDS machinery to something more generic
2 parents d7b8f8e + 8e786a8 commit 6e9128f

File tree

23 files changed

+418
-53
lines changed

23 files changed

+418
-53
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ What: /sys/devices/system/cpu/vulnerabilities
584584
/sys/devices/system/cpu/vulnerabilities/spectre_v1
585585
/sys/devices/system/cpu/vulnerabilities/spectre_v2
586586
/sys/devices/system/cpu/vulnerabilities/srbds
587+
/sys/devices/system/cpu/vulnerabilities/tsa
587588
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
588589
Date: January 2018
589590
Contact: Linux kernel mailing list <[email protected]>

Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,7 @@ This is achieved by using the otherwise unused and obsolete VERW instruction in
157157
combination with a microcode update. The microcode clears the affected CPU
158158
buffers when the VERW instruction is executed.
159159

160-
Kernel reuses the MDS function to invoke the buffer clearing:
161-
162-
mds_clear_cpu_buffers()
160+
Kernel does the buffer clearing with x86_clear_cpu_buffers().
163161

164162
On MDS affected CPUs, the kernel already invokes CPU buffer clear on
165163
kernel/userspace, hypervisor/guest and C-state (idle) transitions. No

Documentation/admin-guide/kernel-parameters.txt

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

7491+
tsa= [X86] Control mitigation for Transient Scheduler
7492+
Attacks on AMD CPUs. Search the following in your
7493+
favourite search engine for more details:
7494+
7495+
"Technical guidance for mitigating transient scheduler
7496+
attacks".
7497+
7498+
off - disable the mitigation
7499+
on - enable the mitigation (default)
7500+
user - mitigate only user/kernel transitions
7501+
vm - mitigate only guest/host transitions
7502+
7503+
74917504
tsc= Disable clocksource stability checks for TSC.
74927505
Format: <string>
74937506
[x86] reliable: mark tsc clocksource as reliable, this

Documentation/arch/x86/mds.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ enters a C-state.
9393

9494
The kernel provides a function to invoke the buffer clearing:
9595

96-
mds_clear_cpu_buffers()
96+
x86_clear_cpu_buffers()
9797

9898
Also macro CLEAR_CPU_BUFFERS can be used in ASM late in exit-to-user path.
9999
Other than CFLAGS.ZF, this macro doesn't clobber any registers.
@@ -185,9 +185,9 @@ Mitigation points
185185
idle clearing would be a window dressing exercise and is therefore not
186186
activated.
187187

188-
The invocation is controlled by the static key mds_idle_clear which is
189-
switched depending on the chosen mitigation mode and the SMT state of
190-
the system.
188+
The invocation is controlled by the static key cpu_buf_idle_clear which is
189+
switched depending on the chosen mitigation mode and the SMT state of the
190+
system.
191191

192192
The buffer clear is only invoked before entering the C-State to prevent
193193
that stale data from the idling CPU from spilling to the Hyper-Thread

arch/x86/Kconfig

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

2698+
config MITIGATION_TSA
2699+
bool "Mitigate Transient Scheduler Attacks"
2700+
depends on CPU_SUP_AMD
2701+
default y
2702+
help
2703+
Enable mitigation for Transient Scheduler Attacks. TSA is a hardware
2704+
security vulnerability on AMD CPUs which can lead to forwarding of
2705+
invalid info to subsequent instructions and thus can affect their
2706+
timing and thereby cause a leakage.
26982707
endif
26992708

27002709
config ARCH_HAS_ADD_PAGES

arch/x86/entry/entry.S

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,20 @@ EXPORT_SYMBOL_GPL(write_ibpb);
3636

3737
/*
3838
* Define the VERW operand that is disguised as entry code so that
39-
* it can be referenced with KPTI enabled. This ensure VERW can be
39+
* it can be referenced with KPTI enabled. This ensures VERW can be
4040
* used late in exit-to-user path after page tables are switched.
4141
*/
4242
.pushsection .entry.text, "ax"
4343

4444
.align L1_CACHE_BYTES, 0xcc
45-
SYM_CODE_START_NOALIGN(mds_verw_sel)
45+
SYM_CODE_START_NOALIGN(x86_verw_sel)
4646
UNWIND_HINT_UNDEFINED
4747
ANNOTATE_NOENDBR
4848
.word __KERNEL_DS
4949
.align L1_CACHE_BYTES, 0xcc
50-
SYM_CODE_END(mds_verw_sel);
50+
SYM_CODE_END(x86_verw_sel);
5151
/* For KVM */
52-
EXPORT_SYMBOL_GPL(mds_verw_sel);
52+
EXPORT_SYMBOL_GPL(x86_verw_sel);
5353

5454
.popsection
5555

arch/x86/include/asm/cpufeatures.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@
456456
#define X86_FEATURE_NO_NESTED_DATA_BP (20*32+ 0) /* No Nested Data Breakpoints */
457457
#define X86_FEATURE_WRMSR_XX_BASE_NS (20*32+ 1) /* WRMSR to {FS,GS,KERNEL_GS}_BASE is non-serializing */
458458
#define X86_FEATURE_LFENCE_RDTSC (20*32+ 2) /* LFENCE always serializing / synchronizes RDTSC */
459+
#define X86_FEATURE_VERW_CLEAR (20*32+ 5) /* The memory form of VERW mitigates TSA */
459460
#define X86_FEATURE_NULL_SEL_CLR_BASE (20*32+ 6) /* Null Selector Clears Base */
460461
#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* Automatic IBRS */
461462
#define X86_FEATURE_NO_SMM_CTL_MSR (20*32+ 9) /* SMM_CTL MSR is not present */
@@ -487,6 +488,9 @@
487488
#define X86_FEATURE_PREFER_YMM (21*32+ 8) /* Avoid ZMM registers due to downclocking */
488489
#define X86_FEATURE_APX (21*32+ 9) /* Advanced Performance Extensions */
489490
#define X86_FEATURE_INDIRECT_THUNK_ITS (21*32+10) /* Use thunk for indirect branches in lower half of cacheline */
491+
#define X86_FEATURE_TSA_SQ_NO (21*32+11) /* AMD CPU not vulnerable to TSA-SQ */
492+
#define X86_FEATURE_TSA_L1_NO (21*32+12) /* AMD CPU not vulnerable to TSA-L1 */
493+
#define X86_FEATURE_CLEAR_CPU_BUF_VM (21*32+13) /* Clear CPU buffers using VERW before VMRUN */
490494

491495
/*
492496
* BUG word(s)
@@ -542,5 +546,5 @@
542546
#define X86_BUG_OLD_MICROCODE X86_BUG( 1*32+ 6) /* "old_microcode" CPU has old microcode, it is surely vulnerable to something */
543547
#define X86_BUG_ITS X86_BUG( 1*32+ 7) /* "its" CPU is affected by Indirect Target Selection */
544548
#define X86_BUG_ITS_NATIVE_ONLY X86_BUG( 1*32+ 8) /* "its_native_only" CPU is affected by ITS, VMX is not affected */
545-
549+
#define X86_BUG_TSA X86_BUG( 1*32+ 9) /* "tsa" CPU is affected by Transient Scheduler Attacks */
546550
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/include/asm/irqflags.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ static __always_inline void native_irq_enable(void)
4444

4545
static __always_inline void native_safe_halt(void)
4646
{
47-
mds_idle_clear_cpu_buffers();
47+
x86_idle_clear_cpu_buffers();
4848
asm volatile("sti; hlt": : :"memory");
4949
}
5050

5151
static __always_inline void native_halt(void)
5252
{
53-
mds_idle_clear_cpu_buffers();
53+
x86_idle_clear_cpu_buffers();
5454
asm volatile("hlt": : :"memory");
5555
}
5656

arch/x86/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ enum kvm_only_cpuid_leafs {
764764
CPUID_8000_0022_EAX,
765765
CPUID_7_2_EDX,
766766
CPUID_24_0_EBX,
767+
CPUID_8000_0021_ECX,
767768
NR_KVM_CPU_CAPS,
768769

769770
NKVMCAPINTS = NR_KVM_CPU_CAPS - NCAPINTS,

arch/x86/include/asm/mwait.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ static __always_inline void __monitorx(const void *eax, u32 ecx, u32 edx)
4343

4444
static __always_inline void __mwait(u32 eax, u32 ecx)
4545
{
46-
mds_idle_clear_cpu_buffers();
47-
4846
/*
4947
* Use the instruction mnemonic with implicit operands, as the LLVM
5048
* assembler fails to assemble the mnemonic with explicit operands:
@@ -80,7 +78,7 @@ static __always_inline void __mwait(u32 eax, u32 ecx)
8078
*/
8179
static __always_inline void __mwaitx(u32 eax, u32 ebx, u32 ecx)
8280
{
83-
/* No MDS buffer clear as this is AMD/HYGON only */
81+
/* No need for TSA buffer clearing on AMD */
8482

8583
/* "mwaitx %eax, %ebx, %ecx" */
8684
asm volatile(".byte 0x0f, 0x01, 0xfb"
@@ -98,7 +96,6 @@ static __always_inline void __mwaitx(u32 eax, u32 ebx, u32 ecx)
9896
*/
9997
static __always_inline void __sti_mwait(u32 eax, u32 ecx)
10098
{
101-
mds_idle_clear_cpu_buffers();
10299

103100
asm volatile("sti; mwait" :: "a" (eax), "c" (ecx));
104101
}
@@ -115,21 +112,29 @@ static __always_inline void __sti_mwait(u32 eax, u32 ecx)
115112
*/
116113
static __always_inline void mwait_idle_with_hints(u32 eax, u32 ecx)
117114
{
115+
if (need_resched())
116+
return;
117+
118+
x86_idle_clear_cpu_buffers();
119+
118120
if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
119121
const void *addr = &current_thread_info()->flags;
120122

121123
alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
122124
__monitor(addr, 0, 0);
123125

124-
if (!need_resched()) {
125-
if (ecx & 1) {
126-
__mwait(eax, ecx);
127-
} else {
128-
__sti_mwait(eax, ecx);
129-
raw_local_irq_disable();
130-
}
126+
if (need_resched())
127+
goto out;
128+
129+
if (ecx & 1) {
130+
__mwait(eax, ecx);
131+
} else {
132+
__sti_mwait(eax, ecx);
133+
raw_local_irq_disable();
131134
}
132135
}
136+
137+
out:
133138
current_clr_polling();
134139
}
135140

0 commit comments

Comments
 (0)