195c5824fSPawan Gupta // SPDX-License-Identifier: GPL-2.0 295c5824fSPawan Gupta /* 395c5824fSPawan Gupta * Intel Transactional Synchronization Extensions (TSX) control. 495c5824fSPawan Gupta * 595c5824fSPawan Gupta * Copyright (C) 2019 Intel Corporation 695c5824fSPawan Gupta * 795c5824fSPawan Gupta * Author: 895c5824fSPawan Gupta * Pawan Gupta <pawan.kumar.gupta@linux.intel.com> 995c5824fSPawan Gupta */ 1095c5824fSPawan Gupta 1195c5824fSPawan Gupta #include <linux/cpufeature.h> 1295c5824fSPawan Gupta 1395c5824fSPawan Gupta #include <asm/cmdline.h> 1495c5824fSPawan Gupta 1595c5824fSPawan Gupta #include "cpu.h" 1695c5824fSPawan Gupta 1795c5824fSPawan Gupta enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED; 1895c5824fSPawan Gupta 1995c5824fSPawan Gupta void tsx_disable(void) 2095c5824fSPawan Gupta { 2195c5824fSPawan Gupta u64 tsx; 2295c5824fSPawan Gupta 2395c5824fSPawan Gupta rdmsrl(MSR_IA32_TSX_CTRL, tsx); 2495c5824fSPawan Gupta 2595c5824fSPawan Gupta /* Force all transactions to immediately abort */ 2695c5824fSPawan Gupta tsx |= TSX_CTRL_RTM_DISABLE; 2795c5824fSPawan Gupta 2895c5824fSPawan Gupta /* 2995c5824fSPawan Gupta * Ensure TSX support is not enumerated in CPUID. 3095c5824fSPawan Gupta * This is visible to userspace and will ensure they 3195c5824fSPawan Gupta * do not waste resources trying TSX transactions that 3295c5824fSPawan Gupta * will always abort. 3395c5824fSPawan Gupta */ 3495c5824fSPawan Gupta tsx |= TSX_CTRL_CPUID_CLEAR; 3595c5824fSPawan Gupta 3695c5824fSPawan Gupta wrmsrl(MSR_IA32_TSX_CTRL, tsx); 3795c5824fSPawan Gupta } 3895c5824fSPawan Gupta 3995c5824fSPawan Gupta void tsx_enable(void) 4095c5824fSPawan Gupta { 4195c5824fSPawan Gupta u64 tsx; 4295c5824fSPawan Gupta 4395c5824fSPawan Gupta rdmsrl(MSR_IA32_TSX_CTRL, tsx); 4495c5824fSPawan Gupta 4595c5824fSPawan Gupta /* Enable the RTM feature in the cpu */ 4695c5824fSPawan Gupta tsx &= ~TSX_CTRL_RTM_DISABLE; 4795c5824fSPawan Gupta 4895c5824fSPawan Gupta /* 4995c5824fSPawan Gupta * Ensure TSX support is enumerated in CPUID. 5095c5824fSPawan Gupta * This is visible to userspace and will ensure they 5195c5824fSPawan Gupta * can enumerate and use the TSX feature. 5295c5824fSPawan Gupta */ 5395c5824fSPawan Gupta tsx &= ~TSX_CTRL_CPUID_CLEAR; 5495c5824fSPawan Gupta 5595c5824fSPawan Gupta wrmsrl(MSR_IA32_TSX_CTRL, tsx); 5695c5824fSPawan Gupta } 5795c5824fSPawan Gupta 5895c5824fSPawan Gupta static bool __init tsx_ctrl_is_supported(void) 5995c5824fSPawan Gupta { 6095c5824fSPawan Gupta u64 ia32_cap = x86_read_arch_cap_msr(); 6195c5824fSPawan Gupta 6295c5824fSPawan Gupta /* 6395c5824fSPawan Gupta * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this 6495c5824fSPawan Gupta * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES. 6595c5824fSPawan Gupta * 6695c5824fSPawan Gupta * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a 6795c5824fSPawan Gupta * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES 6895c5824fSPawan Gupta * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get 6995c5824fSPawan Gupta * MSR_IA32_TSX_CTRL support even after a microcode update. Thus, 7095c5824fSPawan Gupta * tsx= cmdline requests will do nothing on CPUs without 7195c5824fSPawan Gupta * MSR_IA32_TSX_CTRL support. 7295c5824fSPawan Gupta */ 7395c5824fSPawan Gupta return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR); 7495c5824fSPawan Gupta } 7595c5824fSPawan Gupta 7695c5824fSPawan Gupta void __init tsx_init(void) 7795c5824fSPawan Gupta { 78*7531a359SPawan Gupta char arg[5] = {}; 7995c5824fSPawan Gupta int ret; 8095c5824fSPawan Gupta 8195c5824fSPawan Gupta if (!tsx_ctrl_is_supported()) 8295c5824fSPawan Gupta return; 8395c5824fSPawan Gupta 8495c5824fSPawan Gupta ret = cmdline_find_option(boot_command_line, "tsx", arg, sizeof(arg)); 8595c5824fSPawan Gupta if (ret >= 0) { 8695c5824fSPawan Gupta if (!strcmp(arg, "on")) { 8795c5824fSPawan Gupta tsx_ctrl_state = TSX_CTRL_ENABLE; 8895c5824fSPawan Gupta } else if (!strcmp(arg, "off")) { 8995c5824fSPawan Gupta tsx_ctrl_state = TSX_CTRL_DISABLE; 90*7531a359SPawan Gupta } else if (!strcmp(arg, "auto")) { 91*7531a359SPawan Gupta if (boot_cpu_has_bug(X86_BUG_TAA)) 92*7531a359SPawan Gupta tsx_ctrl_state = TSX_CTRL_DISABLE; 93*7531a359SPawan Gupta else 94*7531a359SPawan Gupta tsx_ctrl_state = TSX_CTRL_ENABLE; 9595c5824fSPawan Gupta } else { 9695c5824fSPawan Gupta tsx_ctrl_state = TSX_CTRL_DISABLE; 9795c5824fSPawan Gupta pr_err("tsx: invalid option, defaulting to off\n"); 9895c5824fSPawan Gupta } 9995c5824fSPawan Gupta } else { 10095c5824fSPawan Gupta /* tsx= not provided, defaulting to off */ 10195c5824fSPawan Gupta tsx_ctrl_state = TSX_CTRL_DISABLE; 10295c5824fSPawan Gupta } 10395c5824fSPawan Gupta 10495c5824fSPawan Gupta if (tsx_ctrl_state == TSX_CTRL_DISABLE) { 10595c5824fSPawan Gupta tsx_disable(); 10695c5824fSPawan Gupta 10795c5824fSPawan Gupta /* 10895c5824fSPawan Gupta * tsx_disable() will change the state of the 10995c5824fSPawan Gupta * RTM CPUID bit. Clear it here since it is now 11095c5824fSPawan Gupta * expected to be not set. 11195c5824fSPawan Gupta */ 11295c5824fSPawan Gupta setup_clear_cpu_cap(X86_FEATURE_RTM); 11395c5824fSPawan Gupta } else if (tsx_ctrl_state == TSX_CTRL_ENABLE) { 11495c5824fSPawan Gupta 11595c5824fSPawan Gupta /* 11695c5824fSPawan Gupta * HW defaults TSX to be enabled at bootup. 11795c5824fSPawan Gupta * We may still need the TSX enable support 11895c5824fSPawan Gupta * during init for special cases like 11995c5824fSPawan Gupta * kexec after TSX is disabled. 12095c5824fSPawan Gupta */ 12195c5824fSPawan Gupta tsx_enable(); 12295c5824fSPawan Gupta 12395c5824fSPawan Gupta /* 12495c5824fSPawan Gupta * tsx_enable() will change the state of the 12595c5824fSPawan Gupta * RTM CPUID bit. Force it here since it is now 12695c5824fSPawan Gupta * expected to be set. 12795c5824fSPawan Gupta */ 12895c5824fSPawan Gupta setup_force_cpu_cap(X86_FEATURE_RTM); 12995c5824fSPawan Gupta } 13095c5824fSPawan Gupta } 131