19
19
20
20
enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED ;
21
21
22
- void tsx_disable (void )
22
+ static void tsx_disable (void )
23
23
{
24
24
u64 tsx ;
25
25
@@ -39,7 +39,7 @@ void tsx_disable(void)
39
39
wrmsrl (MSR_IA32_TSX_CTRL , tsx );
40
40
}
41
41
42
- void tsx_enable (void )
42
+ static void tsx_enable (void )
43
43
{
44
44
u64 tsx ;
45
45
@@ -58,7 +58,7 @@ void tsx_enable(void)
58
58
wrmsrl (MSR_IA32_TSX_CTRL , tsx );
59
59
}
60
60
61
- static bool __init tsx_ctrl_is_supported (void )
61
+ static bool tsx_ctrl_is_supported (void )
62
62
{
63
63
u64 ia32_cap = x86_read_arch_cap_msr ();
64
64
@@ -84,7 +84,45 @@ static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
84
84
return TSX_CTRL_ENABLE ;
85
85
}
86
86
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 )
88
126
{
89
127
u64 msr ;
90
128
@@ -97,6 +135,39 @@ void tsx_clear_cpuid(void)
97
135
rdmsrl (MSR_TSX_FORCE_ABORT , msr );
98
136
msr |= MSR_TFA_TSX_CPUID_CLEAR ;
99
137
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 );
100
171
}
101
172
}
102
173
@@ -105,14 +176,14 @@ void __init tsx_init(void)
105
176
char arg [5 ] = {};
106
177
int ret ;
107
178
179
+ tsx_dev_mode_disable ();
180
+
108
181
/*
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.
113
185
*/
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 )) {
116
187
tsx_ctrl_state = TSX_CTRL_RTM_ALWAYS_ABORT ;
117
188
tsx_clear_cpuid ();
118
189
setup_clear_cpu_cap (X86_FEATURE_RTM );
@@ -175,3 +246,16 @@ void __init tsx_init(void)
175
246
setup_force_cpu_cap (X86_FEATURE_HLE );
176
247
}
177
248
}
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
+ }
0 commit comments