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