Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Intel Transactional Synchronization Extensions (TSX) control.
  4 *
  5 * Copyright (C) 2019 Intel Corporation
  6 *
  7 * Author:
  8 *	Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
  9 */
 10
 11#include <linux/cpufeature.h>
 12
 13#include <asm/cmdline.h>
 14
 15#include "cpu.h"
 16
 17#undef pr_fmt
 18#define pr_fmt(fmt) "tsx: " fmt
 19
 20enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED;
 21
 22void tsx_disable(void)
 23{
 24	u64 tsx;
 25
 26	rdmsrl(MSR_IA32_TSX_CTRL, tsx);
 27
 28	/* Force all transactions to immediately abort */
 29	tsx |= TSX_CTRL_RTM_DISABLE;
 30
 31	/*
 32	 * Ensure TSX support is not enumerated in CPUID.
 33	 * This is visible to userspace and will ensure they
 34	 * do not waste resources trying TSX transactions that
 35	 * will always abort.
 36	 */
 37	tsx |= TSX_CTRL_CPUID_CLEAR;
 38
 39	wrmsrl(MSR_IA32_TSX_CTRL, tsx);
 40}
 41
 42void tsx_enable(void)
 43{
 44	u64 tsx;
 45
 46	rdmsrl(MSR_IA32_TSX_CTRL, tsx);
 47
 48	/* Enable the RTM feature in the cpu */
 49	tsx &= ~TSX_CTRL_RTM_DISABLE;
 50
 51	/*
 52	 * Ensure TSX support is enumerated in CPUID.
 53	 * This is visible to userspace and will ensure they
 54	 * can enumerate and use the TSX feature.
 55	 */
 56	tsx &= ~TSX_CTRL_CPUID_CLEAR;
 57
 58	wrmsrl(MSR_IA32_TSX_CTRL, tsx);
 59}
 60
 61static bool __init tsx_ctrl_is_supported(void)
 62{
 63	u64 ia32_cap = x86_read_arch_cap_msr();
 64
 65	/*
 66	 * TSX is controlled via MSR_IA32_TSX_CTRL.  However, support for this
 67	 * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
 68	 *
 69	 * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
 70	 * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
 71	 * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
 72	 * MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
 73	 * tsx= cmdline requests will do nothing on CPUs without
 74	 * MSR_IA32_TSX_CTRL support.
 75	 */
 76	return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
 77}
 78
 79static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
 80{
 81	if (boot_cpu_has_bug(X86_BUG_TAA))
 82		return TSX_CTRL_DISABLE;
 83
 84	return TSX_CTRL_ENABLE;
 85}
 86
 87void __init tsx_init(void)
 88{
 89	char arg[5] = {};
 90	int ret;
 91
 92	if (!tsx_ctrl_is_supported())
 93		return;
 94
 95	ret = cmdline_find_option(boot_command_line, "tsx", arg, sizeof(arg));
 96	if (ret >= 0) {
 97		if (!strcmp(arg, "on")) {
 98			tsx_ctrl_state = TSX_CTRL_ENABLE;
 99		} else if (!strcmp(arg, "off")) {
100			tsx_ctrl_state = TSX_CTRL_DISABLE;
101		} else if (!strcmp(arg, "auto")) {
102			tsx_ctrl_state = x86_get_tsx_auto_mode();
103		} else {
104			tsx_ctrl_state = TSX_CTRL_DISABLE;
105			pr_err("invalid option, defaulting to off\n");
106		}
107	} else {
108		/* tsx= not provided */
109		if (IS_ENABLED(CONFIG_X86_INTEL_TSX_MODE_AUTO))
110			tsx_ctrl_state = x86_get_tsx_auto_mode();
111		else if (IS_ENABLED(CONFIG_X86_INTEL_TSX_MODE_OFF))
112			tsx_ctrl_state = TSX_CTRL_DISABLE;
113		else
114			tsx_ctrl_state = TSX_CTRL_ENABLE;
115	}
116
117	if (tsx_ctrl_state == TSX_CTRL_DISABLE) {
118		tsx_disable();
119
120		/*
121		 * tsx_disable() will change the state of the RTM and HLE CPUID
122		 * bits. Clear them here since they are now expected to be not
123		 * set.
124		 */
125		setup_clear_cpu_cap(X86_FEATURE_RTM);
126		setup_clear_cpu_cap(X86_FEATURE_HLE);
127	} else if (tsx_ctrl_state == TSX_CTRL_ENABLE) {
128
129		/*
130		 * HW defaults TSX to be enabled at bootup.
131		 * We may still need the TSX enable support
132		 * during init for special cases like
133		 * kexec after TSX is disabled.
134		 */
135		tsx_enable();
136
137		/*
138		 * tsx_enable() will change the state of the RTM and HLE CPUID
139		 * bits. Force them here since they are now expected to be set.
140		 */
141		setup_force_cpu_cap(X86_FEATURE_RTM);
142		setup_force_cpu_cap(X86_FEATURE_HLE);
143	}
144}