@@ -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,6 +84,44 @@ static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
84
84
return TSX_CTRL_ENABLE ;
85
85
}
86
86
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
+ */
87
125
void tsx_clear_cpuid (void )
88
126
{
89
127
u64 msr ;
@@ -97,6 +135,10 @@ 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 );
100
142
}
101
143
}
102
144
@@ -106,13 +148,11 @@ void __init tsx_init(void)
106
148
int ret ;
107
149
108
150
/*
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.
151
+ * Hardware will always abort a TSX transaction when the CPUID bit
152
+ * RTM_ALWAYS_ABORT is set. In this case, it is better not to enumerate
153
+ * CPUID.RTM and CPUID.HLE bits. Clear them here.
113
154
*/
114
- if (boot_cpu_has (X86_FEATURE_RTM_ALWAYS_ABORT ) &&
115
- boot_cpu_has (X86_FEATURE_TSX_FORCE_ABORT )) {
155
+ if (boot_cpu_has (X86_FEATURE_RTM_ALWAYS_ABORT )) {
116
156
tsx_ctrl_state = TSX_CTRL_RTM_ALWAYS_ABORT ;
117
157
tsx_clear_cpuid ();
118
158
setup_clear_cpu_cap (X86_FEATURE_RTM );
0 commit comments