tsx.c 3.4 KB

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