root/arch/x86/kernel/cpu/tsx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tsx_disable
  2. tsx_enable
  3. tsx_ctrl_is_supported
  4. x86_get_tsx_auto_mode
  5. tsx_init

   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 RTM and HLE CPUID
 119                  * bits. Clear them here since they are now expected to be not
 120                  * set.
 121                  */
 122                 setup_clear_cpu_cap(X86_FEATURE_RTM);
 123                 setup_clear_cpu_cap(X86_FEATURE_HLE);
 124         } else if (tsx_ctrl_state == TSX_CTRL_ENABLE) {
 125 
 126                 /*
 127                  * HW defaults TSX to be enabled at bootup.
 128                  * We may still need the TSX enable support
 129                  * during init for special cases like
 130                  * kexec after TSX is disabled.
 131                  */
 132                 tsx_enable();
 133 
 134                 /*
 135                  * tsx_enable() will change the state of the RTM and HLE CPUID
 136                  * bits. Force them here since they are now expected to be set.
 137                  */
 138                 setup_force_cpu_cap(X86_FEATURE_RTM);
 139                 setup_force_cpu_cap(X86_FEATURE_HLE);
 140         }
 141 }

/* [<][>][^][v][top][bottom][index][help] */