Line data Source code
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 : 20 : enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED; 21 : 22 0 : void tsx_disable(void) 23 : { 24 0 : u64 tsx; 25 : 26 0 : rdmsrl(MSR_IA32_TSX_CTRL, tsx); 27 : 28 : /* Force all transactions to immediately abort */ 29 0 : 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 0 : tsx |= TSX_CTRL_CPUID_CLEAR; 38 : 39 0 : wrmsrl(MSR_IA32_TSX_CTRL, tsx); 40 0 : } 41 : 42 0 : void tsx_enable(void) 43 : { 44 0 : u64 tsx; 45 : 46 0 : rdmsrl(MSR_IA32_TSX_CTRL, tsx); 47 : 48 : /* Enable the RTM feature in the cpu */ 49 0 : 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 0 : tsx &= ~TSX_CTRL_CPUID_CLEAR; 57 : 58 0 : wrmsrl(MSR_IA32_TSX_CTRL, tsx); 59 0 : } 60 : 61 1 : static bool __init tsx_ctrl_is_supported(void) 62 : { 63 1 : 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 1 : return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR); 77 : } 78 : 79 0 : static enum tsx_ctrl_states x86_get_tsx_auto_mode(void) 80 : { 81 0 : if (boot_cpu_has_bug(X86_BUG_TAA)) 82 0 : return TSX_CTRL_DISABLE; 83 : 84 : return TSX_CTRL_ENABLE; 85 : } 86 : 87 1 : void __init tsx_init(void) 88 : { 89 1 : char arg[5] = {}; 90 1 : int ret; 91 : 92 1 : if (!tsx_ctrl_is_supported()) 93 1 : return; 94 : 95 0 : ret = cmdline_find_option(boot_command_line, "tsx", arg, sizeof(arg)); 96 0 : if (ret >= 0) { 97 0 : if (!strcmp(arg, "on")) { 98 0 : tsx_ctrl_state = TSX_CTRL_ENABLE; 99 0 : } else if (!strcmp(arg, "off")) { 100 0 : tsx_ctrl_state = TSX_CTRL_DISABLE; 101 0 : } else if (!strcmp(arg, "auto")) { 102 0 : tsx_ctrl_state = x86_get_tsx_auto_mode(); 103 : } else { 104 0 : tsx_ctrl_state = TSX_CTRL_DISABLE; 105 0 : pr_err("invalid option, defaulting to off\n"); 106 : } 107 : } else { 108 : /* tsx= not provided */ 109 0 : if (IS_ENABLED(CONFIG_X86_INTEL_TSX_MODE_AUTO)) 110 : tsx_ctrl_state = x86_get_tsx_auto_mode(); 111 0 : else if (IS_ENABLED(CONFIG_X86_INTEL_TSX_MODE_OFF)) 112 0 : tsx_ctrl_state = TSX_CTRL_DISABLE; 113 : else 114 : tsx_ctrl_state = TSX_CTRL_ENABLE; 115 : } 116 : 117 0 : if (tsx_ctrl_state == TSX_CTRL_DISABLE) { 118 0 : 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 0 : setup_clear_cpu_cap(X86_FEATURE_RTM); 126 0 : setup_clear_cpu_cap(X86_FEATURE_HLE); 127 0 : } 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 0 : 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 0 : setup_force_cpu_cap(X86_FEATURE_RTM); 142 0 : setup_force_cpu_cap(X86_FEATURE_HLE); 143 : } 144 : }