Skip to content

Commit 3a69a44

Browse files
committed
Merge tag 'x86-urgent-2022-04-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: "Two x86 fixes related to TSX: - Use either MSR_TSX_FORCE_ABORT or MSR_IA32_TSX_CTRL to disable TSX to cover all CPUs which allow to disable it. - Disable TSX development mode at boot so that a microcode update which provides TSX development mode does not suddenly make the system vulnerable to TSX Asynchronous Abort" * tag 'x86-urgent-2022-04-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/tsx: Disable TSX development mode at boot x86/tsx: Use MSR_TSX_CTRL to clear CPUID bits
2 parents fbb9c58 + 400331f commit 3a69a44

File tree

6 files changed

+102
-24
lines changed

6 files changed

+102
-24
lines changed

arch/x86/include/asm/msr-index.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@
128128
#define TSX_CTRL_RTM_DISABLE BIT(0) /* Disable RTM feature */
129129
#define TSX_CTRL_CPUID_CLEAR BIT(1) /* Disable TSX enumeration */
130130

131-
/* SRBDS support */
132131
#define MSR_IA32_MCU_OPT_CTRL 0x00000123
133-
#define RNGDS_MITG_DIS BIT(0)
132+
#define RNGDS_MITG_DIS BIT(0) /* SRBDS support */
133+
#define RTM_ALLOW BIT(1) /* TSX development mode */
134134

135135
#define MSR_IA32_SYSENTER_CS 0x00000174
136136
#define MSR_IA32_SYSENTER_ESP 0x00000175

arch/x86/kernel/cpu/common.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,8 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
18551855
validate_apic_and_package_id(c);
18561856
x86_spec_ctrl_setup_ap();
18571857
update_srbds_msr();
1858+
1859+
tsx_ap_init();
18581860
}
18591861

18601862
static __init int setup_noclflush(char *arg)

arch/x86/kernel/cpu/cpu.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ enum tsx_ctrl_states {
5555
extern __ro_after_init enum tsx_ctrl_states tsx_ctrl_state;
5656

5757
extern void __init tsx_init(void);
58-
extern void tsx_enable(void);
59-
extern void tsx_disable(void);
60-
extern void tsx_clear_cpuid(void);
58+
void tsx_ap_init(void);
6159
#else
6260
static inline void tsx_init(void) { }
61+
static inline void tsx_ap_init(void) { }
6362
#endif /* CONFIG_CPU_SUP_INTEL */
6463

6564
extern void get_cpu_cap(struct cpuinfo_x86 *c);

arch/x86/kernel/cpu/intel.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -717,13 +717,6 @@ static void init_intel(struct cpuinfo_x86 *c)
717717

718718
init_intel_misc_features(c);
719719

720-
if (tsx_ctrl_state == TSX_CTRL_ENABLE)
721-
tsx_enable();
722-
else if (tsx_ctrl_state == TSX_CTRL_DISABLE)
723-
tsx_disable();
724-
else if (tsx_ctrl_state == TSX_CTRL_RTM_ALWAYS_ABORT)
725-
tsx_clear_cpuid();
726-
727720
split_lock_init();
728721
bus_lock_init();
729722

arch/x86/kernel/cpu/tsx.c

Lines changed: 94 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED;
2121

22-
void tsx_disable(void)
22+
static void tsx_disable(void)
2323
{
2424
u64 tsx;
2525

@@ -39,7 +39,7 @@ void tsx_disable(void)
3939
wrmsrl(MSR_IA32_TSX_CTRL, tsx);
4040
}
4141

42-
void tsx_enable(void)
42+
static void tsx_enable(void)
4343
{
4444
u64 tsx;
4545

@@ -58,7 +58,7 @@ void tsx_enable(void)
5858
wrmsrl(MSR_IA32_TSX_CTRL, tsx);
5959
}
6060

61-
static bool __init tsx_ctrl_is_supported(void)
61+
static bool tsx_ctrl_is_supported(void)
6262
{
6363
u64 ia32_cap = x86_read_arch_cap_msr();
6464

@@ -84,7 +84,45 @@ static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
8484
return TSX_CTRL_ENABLE;
8585
}
8686

87-
void tsx_clear_cpuid(void)
87+
/*
88+
* Disabling TSX is not a trivial business.
89+
*
90+
* First of all, there's a CPUID bit: X86_FEATURE_RTM_ALWAYS_ABORT
91+
* which says that TSX is practically disabled (all transactions are
92+
* aborted by default). When that bit is set, the kernel unconditionally
93+
* disables TSX.
94+
*
95+
* In order to do that, however, it needs to dance a bit:
96+
*
97+
* 1. The first method to disable it is through MSR_TSX_FORCE_ABORT and
98+
* the MSR is present only when *two* CPUID bits are set:
99+
*
100+
* - X86_FEATURE_RTM_ALWAYS_ABORT
101+
* - X86_FEATURE_TSX_FORCE_ABORT
102+
*
103+
* 2. The second method is for CPUs which do not have the above-mentioned
104+
* MSR: those use a different MSR - MSR_IA32_TSX_CTRL and disable TSX
105+
* through that one. Those CPUs can also have the initially mentioned
106+
* CPUID bit X86_FEATURE_RTM_ALWAYS_ABORT set and for those the same strategy
107+
* applies: TSX gets disabled unconditionally.
108+
*
109+
* When either of the two methods are present, the kernel disables TSX and
110+
* clears the respective RTM and HLE feature flags.
111+
*
112+
* An additional twist in the whole thing presents late microcode loading
113+
* which, when done, may cause for the X86_FEATURE_RTM_ALWAYS_ABORT CPUID
114+
* bit to be set after the update.
115+
*
116+
* A subsequent hotplug operation on any logical CPU except the BSP will
117+
* cause for the supported CPUID feature bits to get re-detected and, if
118+
* RTM and HLE get cleared all of a sudden, but, userspace did consult
119+
* them before the update, then funny explosions will happen. Long story
120+
* short: the kernel doesn't modify CPUID feature bits after booting.
121+
*
122+
* That's why, this function's call in init_intel() doesn't clear the
123+
* feature flags.
124+
*/
125+
static void tsx_clear_cpuid(void)
88126
{
89127
u64 msr;
90128

@@ -97,6 +135,39 @@ void tsx_clear_cpuid(void)
97135
rdmsrl(MSR_TSX_FORCE_ABORT, msr);
98136
msr |= MSR_TFA_TSX_CPUID_CLEAR;
99137
wrmsrl(MSR_TSX_FORCE_ABORT, msr);
138+
} else if (tsx_ctrl_is_supported()) {
139+
rdmsrl(MSR_IA32_TSX_CTRL, msr);
140+
msr |= TSX_CTRL_CPUID_CLEAR;
141+
wrmsrl(MSR_IA32_TSX_CTRL, msr);
142+
}
143+
}
144+
145+
/*
146+
* Disable TSX development mode
147+
*
148+
* When the microcode released in Feb 2022 is applied, TSX will be disabled by
149+
* default on some processors. MSR 0x122 (TSX_CTRL) and MSR 0x123
150+
* (IA32_MCU_OPT_CTRL) can be used to re-enable TSX for development, doing so is
151+
* not recommended for production deployments. In particular, applying MD_CLEAR
152+
* flows for mitigation of the Intel TSX Asynchronous Abort (TAA) transient
153+
* execution attack may not be effective on these processors when Intel TSX is
154+
* enabled with updated microcode.
155+
*/
156+
static void tsx_dev_mode_disable(void)
157+
{
158+
u64 mcu_opt_ctrl;
159+
160+
/* Check if RTM_ALLOW exists */
161+
if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() ||
162+
!cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL))
163+
return;
164+
165+
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_opt_ctrl);
166+
167+
if (mcu_opt_ctrl & RTM_ALLOW) {
168+
mcu_opt_ctrl &= ~RTM_ALLOW;
169+
wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_opt_ctrl);
170+
setup_force_cpu_cap(X86_FEATURE_RTM_ALWAYS_ABORT);
100171
}
101172
}
102173

@@ -105,14 +176,14 @@ void __init tsx_init(void)
105176
char arg[5] = {};
106177
int ret;
107178

179+
tsx_dev_mode_disable();
180+
108181
/*
109-
* Hardware will always abort a TSX transaction if both CPUID bits
110-
* RTM_ALWAYS_ABORT and TSX_FORCE_ABORT are set. In this case, it is
111-
* better not to enumerate CPUID.RTM and CPUID.HLE bits. Clear them
112-
* here.
182+
* Hardware will always abort a TSX transaction when the CPUID bit
183+
* RTM_ALWAYS_ABORT is set. In this case, it is better not to enumerate
184+
* CPUID.RTM and CPUID.HLE bits. Clear them here.
113185
*/
114-
if (boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT) &&
115-
boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)) {
186+
if (boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT)) {
116187
tsx_ctrl_state = TSX_CTRL_RTM_ALWAYS_ABORT;
117188
tsx_clear_cpuid();
118189
setup_clear_cpu_cap(X86_FEATURE_RTM);
@@ -175,3 +246,16 @@ void __init tsx_init(void)
175246
setup_force_cpu_cap(X86_FEATURE_HLE);
176247
}
177248
}
249+
250+
void tsx_ap_init(void)
251+
{
252+
tsx_dev_mode_disable();
253+
254+
if (tsx_ctrl_state == TSX_CTRL_ENABLE)
255+
tsx_enable();
256+
else if (tsx_ctrl_state == TSX_CTRL_DISABLE)
257+
tsx_disable();
258+
else if (tsx_ctrl_state == TSX_CTRL_RTM_ALWAYS_ABORT)
259+
/* See comment over that function for more details. */
260+
tsx_clear_cpuid();
261+
}

tools/arch/x86/include/asm/msr-index.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@
128128
#define TSX_CTRL_RTM_DISABLE BIT(0) /* Disable RTM feature */
129129
#define TSX_CTRL_CPUID_CLEAR BIT(1) /* Disable TSX enumeration */
130130

131-
/* SRBDS support */
132131
#define MSR_IA32_MCU_OPT_CTRL 0x00000123
133-
#define RNGDS_MITG_DIS BIT(0)
132+
#define RNGDS_MITG_DIS BIT(0) /* SRBDS support */
133+
#define RTM_ALLOW BIT(1) /* TSX development mode */
134134

135135
#define MSR_IA32_SYSENTER_CS 0x00000174
136136
#define MSR_IA32_SYSENTER_ESP 0x00000175

0 commit comments

Comments
 (0)