Skip to content

Commit

Permalink
x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default
Browse files Browse the repository at this point in the history
Add a kernel cmdline parameter "tsx" to control the Transactional
Synchronization Extensions (TSX) feature. On CPUs that support TSX
control, use "tsx=on|off" to enable or disable TSX. Not specifying this
option is equivalent to "tsx=off". This is because on certain processors
TSX may be used as a part of a speculative side channel attack.

Carve out the TSX controlling functionality into a separate compilation
unit because TSX is a CPU feature while the TSX async abort control
machinery will go to cpu/bugs.c.

 [ bp: - Massage, shorten and clear the arg buffer.
       - Clarifications of the tsx= possible options - Josh.
       - Expand on TSX_CTRL availability - Pawan. ]

Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
  • Loading branch information
pa1gupta authored and Thomas Gleixner committed Oct 28, 2019
1 parent 286836a commit 95c5824
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 1 deletion.
26 changes: 26 additions & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Expand Up @@ -4848,6 +4848,32 @@
interruptions from clocksource watchdog are not
acceptable).

tsx= [X86] Control Transactional Synchronization
Extensions (TSX) feature in Intel processors that
support TSX control.

This parameter controls the TSX feature. The options are:

on - Enable TSX on the system. Although there are
mitigations for all known security vulnerabilities,
TSX has been known to be an accelerator for
several previous speculation-related CVEs, and
so there may be unknown security risks associated
with leaving it enabled.

off - Disable TSX on the system. (Note that this
option takes effect only on newer CPUs which are
not vulnerable to MDS, i.e., have
MSR_IA32_ARCH_CAPABILITIES.MDS_NO=1 and which get
the new IA32_TSX_CTRL MSR through a microcode
update. This new MSR allows for the reliable
deactivation of the TSX functionality.)

Not specifying this option is equivalent to tsx=off.

See Documentation/admin-guide/hw-vuln/tsx_async_abort.rst
for more details.

turbografx.map[2|3]= [HW,JOY]
TurboGraFX parallel port interface
Format:
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/Makefile
Expand Up @@ -30,7 +30,7 @@ obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o

ifdef CONFIG_CPU_SUP_INTEL
obj-y += intel.o intel_pconfig.o
obj-y += intel.o intel_pconfig.o tsx.o
obj-$(CONFIG_PM) += intel_epb.o
endif
obj-$(CONFIG_CPU_SUP_AMD) += amd.o
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/cpu/common.c
Expand Up @@ -1561,6 +1561,8 @@ void __init identify_boot_cpu(void)
#endif
cpu_detect_tlb(&boot_cpu_data);
setup_cr_pinning();

tsx_init();
}

void identify_secondary_cpu(struct cpuinfo_x86 *c)
Expand Down
16 changes: 16 additions & 0 deletions arch/x86/kernel/cpu/cpu.h
Expand Up @@ -44,6 +44,22 @@ struct _tlb_table {
extern const struct cpu_dev *const __x86_cpu_dev_start[],
*const __x86_cpu_dev_end[];

#ifdef CONFIG_CPU_SUP_INTEL
enum tsx_ctrl_states {
TSX_CTRL_ENABLE,
TSX_CTRL_DISABLE,
TSX_CTRL_NOT_SUPPORTED,
};

extern __ro_after_init enum tsx_ctrl_states tsx_ctrl_state;

extern void __init tsx_init(void);
extern void tsx_enable(void);
extern void tsx_disable(void);
#else
static inline void tsx_init(void) { }
#endif /* CONFIG_CPU_SUP_INTEL */

extern void get_cpu_cap(struct cpuinfo_x86 *c);
extern void get_cpu_address_sizes(struct cpuinfo_x86 *c);
extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
Expand Down
5 changes: 5 additions & 0 deletions arch/x86/kernel/cpu/intel.c
Expand Up @@ -762,6 +762,11 @@ static void init_intel(struct cpuinfo_x86 *c)
detect_tme(c);

init_intel_misc_features(c);

if (tsx_ctrl_state == TSX_CTRL_ENABLE)
tsx_enable();
if (tsx_ctrl_state == TSX_CTRL_DISABLE)
tsx_disable();
}

#ifdef CONFIG_X86_32
Expand Down
125 changes: 125 additions & 0 deletions arch/x86/kernel/cpu/tsx.c
@@ -0,0 +1,125 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Intel Transactional Synchronization Extensions (TSX) control.
*
* Copyright (C) 2019 Intel Corporation
*
* Author:
* Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
*/

#include <linux/cpufeature.h>

#include <asm/cmdline.h>

#include "cpu.h"

enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED;

void tsx_disable(void)
{
u64 tsx;

rdmsrl(MSR_IA32_TSX_CTRL, tsx);

/* Force all transactions to immediately abort */
tsx |= TSX_CTRL_RTM_DISABLE;

/*
* Ensure TSX support is not enumerated in CPUID.
* This is visible to userspace and will ensure they
* do not waste resources trying TSX transactions that
* will always abort.
*/
tsx |= TSX_CTRL_CPUID_CLEAR;

wrmsrl(MSR_IA32_TSX_CTRL, tsx);
}

void tsx_enable(void)
{
u64 tsx;

rdmsrl(MSR_IA32_TSX_CTRL, tsx);

/* Enable the RTM feature in the cpu */
tsx &= ~TSX_CTRL_RTM_DISABLE;

/*
* Ensure TSX support is enumerated in CPUID.
* This is visible to userspace and will ensure they
* can enumerate and use the TSX feature.
*/
tsx &= ~TSX_CTRL_CPUID_CLEAR;

wrmsrl(MSR_IA32_TSX_CTRL, tsx);
}

static bool __init tsx_ctrl_is_supported(void)
{
u64 ia32_cap = x86_read_arch_cap_msr();

/*
* TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this
* MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
*
* TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
* microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
* bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
* MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
* tsx= cmdline requests will do nothing on CPUs without
* MSR_IA32_TSX_CTRL support.
*/
return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
}

void __init tsx_init(void)
{
char arg[4] = {};
int ret;

if (!tsx_ctrl_is_supported())
return;

ret = cmdline_find_option(boot_command_line, "tsx", arg, sizeof(arg));
if (ret >= 0) {
if (!strcmp(arg, "on")) {
tsx_ctrl_state = TSX_CTRL_ENABLE;
} else if (!strcmp(arg, "off")) {
tsx_ctrl_state = TSX_CTRL_DISABLE;
} else {
tsx_ctrl_state = TSX_CTRL_DISABLE;
pr_err("tsx: invalid option, defaulting to off\n");
}
} else {
/* tsx= not provided, defaulting to off */
tsx_ctrl_state = TSX_CTRL_DISABLE;
}

if (tsx_ctrl_state == TSX_CTRL_DISABLE) {
tsx_disable();

/*
* tsx_disable() will change the state of the
* RTM CPUID bit. Clear it here since it is now
* expected to be not set.
*/
setup_clear_cpu_cap(X86_FEATURE_RTM);
} else if (tsx_ctrl_state == TSX_CTRL_ENABLE) {

/*
* HW defaults TSX to be enabled at bootup.
* We may still need the TSX enable support
* during init for special cases like
* kexec after TSX is disabled.
*/
tsx_enable();

/*
* tsx_enable() will change the state of the
* RTM CPUID bit. Force it here since it is now
* expected to be set.
*/
setup_force_cpu_cap(X86_FEATURE_RTM);
}
}

0 comments on commit 95c5824

Please sign in to comment.