Branch data 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 : 3 : static bool __init tsx_ctrl_is_supported(void) 62 : : { 63 : 3 : 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 : 3 : 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 : 3 : void __init tsx_init(void) 88 : : { 89 : 3 : char arg[5] = {}; 90 : 3 : int ret; 91 : : 92 [ + - ]: 3 : if (!tsx_ctrl_is_supported()) 93 : 3 : 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 : : }