Skip to content

Commit 2936493

Browse files
pa1guptasuryasaimadhu
authored andcommitted
x86/tsx: Clear CPUID bits when TSX always force aborts
As a result of TSX deprecation, some processors always abort TSX transactions by default after a microcode update. When TSX feature cannot be used it is better to hide it. Clear CPUID.RTM and CPUID.HLE bits when TSX transactions always abort. [ bp: Massage commit message and comments. ] Signed-off-by: Pawan Gupta <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Reviewed-by: Andi Kleen <[email protected]> Reviewed-by: Tony Luck <[email protected]> Tested-by: Neelima Krishnan <[email protected]> Link: https://lkml.kernel.org/r/5209b3d72ffe5bd3cafdcc803f5b883f785329c3.1623704845.git-series.pawan.kumar.gupta@linux.intel.com
1 parent ad3c2e1 commit 2936493

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

arch/x86/kernel/cpu/cpu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[],
4848
enum tsx_ctrl_states {
4949
TSX_CTRL_ENABLE,
5050
TSX_CTRL_DISABLE,
51+
TSX_CTRL_RTM_ALWAYS_ABORT,
5152
TSX_CTRL_NOT_SUPPORTED,
5253
};
5354

@@ -56,6 +57,7 @@ extern __ro_after_init enum tsx_ctrl_states tsx_ctrl_state;
5657
extern void __init tsx_init(void);
5758
extern void tsx_enable(void);
5859
extern void tsx_disable(void);
60+
extern void tsx_clear_cpuid(void);
5961
#else
6062
static inline void tsx_init(void) { }
6163
#endif /* CONFIG_CPU_SUP_INTEL */

arch/x86/kernel/cpu/intel.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,10 @@ static void init_intel(struct cpuinfo_x86 *c)
717717

718718
if (tsx_ctrl_state == TSX_CTRL_ENABLE)
719719
tsx_enable();
720-
if (tsx_ctrl_state == TSX_CTRL_DISABLE)
720+
else if (tsx_ctrl_state == TSX_CTRL_DISABLE)
721721
tsx_disable();
722+
else if (tsx_ctrl_state == TSX_CTRL_RTM_ALWAYS_ABORT)
723+
tsx_clear_cpuid();
722724

723725
split_lock_init();
724726
bus_lock_init();

arch/x86/kernel/cpu/tsx.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/*
33
* Intel Transactional Synchronization Extensions (TSX) control.
44
*
5-
* Copyright (C) 2019 Intel Corporation
5+
* Copyright (C) 2019-2021 Intel Corporation
66
*
77
* Author:
88
* Pawan Gupta <[email protected]>
@@ -84,13 +84,46 @@ static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
8484
return TSX_CTRL_ENABLE;
8585
}
8686

87+
void tsx_clear_cpuid(void)
88+
{
89+
u64 msr;
90+
91+
/*
92+
* MSR_TFA_TSX_CPUID_CLEAR bit is only present when both CPUID
93+
* bits RTM_ALWAYS_ABORT and TSX_FORCE_ABORT are present.
94+
*/
95+
if (boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT) &&
96+
boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)) {
97+
rdmsrl(MSR_TSX_FORCE_ABORT, msr);
98+
msr |= MSR_TFA_TSX_CPUID_CLEAR;
99+
wrmsrl(MSR_TSX_FORCE_ABORT, msr);
100+
}
101+
}
102+
87103
void __init tsx_init(void)
88104
{
89105
char arg[5] = {};
90106
int ret;
91107

92-
if (!tsx_ctrl_is_supported())
108+
/*
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.
113+
*/
114+
if (boot_cpu_has(X86_FEATURE_RTM_ALWAYS_ABORT) &&
115+
boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)) {
116+
tsx_ctrl_state = TSX_CTRL_RTM_ALWAYS_ABORT;
117+
tsx_clear_cpuid();
118+
setup_clear_cpu_cap(X86_FEATURE_RTM);
119+
setup_clear_cpu_cap(X86_FEATURE_HLE);
93120
return;
121+
}
122+
123+
if (!tsx_ctrl_is_supported()) {
124+
tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED;
125+
return;
126+
}
94127

95128
ret = cmdline_find_option(boot_command_line, "tsx", arg, sizeof(arg));
96129
if (ret >= 0) {

0 commit comments

Comments
 (0)