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