summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/libs/guest/xg_cpuid_x86.c2
-rw-r--r--xen/arch/x86/cpuid.c24
-rw-r--r--xen/arch/x86/spec_ctrl.c3
-rw-r--r--xen/arch/x86/tsx.c31
-rw-r--r--xen/include/asm-x86/processor.h1
-rw-r--r--xen/include/public/arch-x86/cpufeatureset.h4
6 files changed, 44 insertions, 21 deletions
diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x86.c
index 1ebc108213..ec5a47fde4 100644
--- a/tools/libs/guest/xg_cpuid_x86.c
+++ b/tools/libs/guest/xg_cpuid_x86.c
@@ -511,6 +511,8 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t domid, bool restore,
* so migrated-in VM's don't risk seeing features disappearing.
*/
p->basic.rdrand = test_bit(X86_FEATURE_RDRAND, host_featureset);
+ p->feat.hle = test_bit(X86_FEATURE_HLE, host_featureset);
+ p->feat.rtm = test_bit(X86_FEATURE_RTM, host_featureset);
if ( di.hvm )
{
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 752bf244ea..55a7b16342 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -375,6 +375,16 @@ static void __init guest_common_default_feature_adjustments(uint32_t *fs)
boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x3a &&
cpu_has_rdrand && !is_forced_cpu_cap(X86_FEATURE_RDRAND) )
__clear_bit(X86_FEATURE_RDRAND, fs);
+
+ /*
+ * On certain hardware, speculative or errata workarounds can result in
+ * TSX being placed in "force-abort" mode, where it doesn't actually
+ * function as expected, but is technically compatible with the ISA.
+ *
+ * Do not advertise RTM to guests by default if it won't actually work.
+ */
+ if ( rtm_disabled )
+ __clear_bit(X86_FEATURE_RTM, fs);
}
static void __init guest_common_feature_adjustments(uint32_t *fs)
@@ -652,20 +662,6 @@ void recalculate_cpuid_policy(struct domain *d)
__clear_bit(X86_FEATURE_SYSCALL, max_fs);
}
- /*
- * On hardware with MSR_TSX_CTRL, the admin may have elected to disable
- * TSX and hide the feature bits. Migrating-in VMs may have been booted
- * pre-mitigation when the TSX features were visbile.
- *
- * This situation is compatible (albeit with a perf hit to any TSX code in
- * the guest), so allow the feature bits to remain set.
- */
- if ( cpu_has_tsx_ctrl )
- {
- __set_bit(X86_FEATURE_HLE, max_fs);
- __set_bit(X86_FEATURE_RTM, max_fs);
- }
-
/* Clamp the toolstacks choices to reality. */
for ( i = 0; i < ARRAY_SIZE(fs); i++ )
fs[i] &= max_fs[i];
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
index cd05f42394..f2782b2d55 100644
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -1158,9 +1158,6 @@ void __init init_speculation_mitigations(void)
((hw_smt_enabled && opt_smt) ||
!boot_cpu_has(X86_FEATURE_SC_VERW_IDLE)) )
{
- setup_clear_cpu_cap(X86_FEATURE_HLE);
- setup_clear_cpu_cap(X86_FEATURE_RTM);
-
opt_tsx = 0;
tsx_init();
}
diff --git a/xen/arch/x86/tsx.c b/xen/arch/x86/tsx.c
index 39e483640a..e09e819dce 100644
--- a/xen/arch/x86/tsx.c
+++ b/xen/arch/x86/tsx.c
@@ -15,6 +15,7 @@
*/
int8_t __read_mostly opt_tsx = -1;
int8_t __read_mostly cpu_has_tsx_ctrl = -1;
+bool __read_mostly rtm_disabled;
static int __init parse_tsx(const char *s)
{
@@ -45,6 +46,30 @@ void tsx_init(void)
rdmsrl(MSR_ARCH_CAPABILITIES, caps);
cpu_has_tsx_ctrl = !!(caps & ARCH_CAPS_TSX_CTRL);
+
+ /*
+ * The TSX features (HLE/RTM) are handled specially. They both
+ * enumerate features but, on certain parts, have mechanisms to be
+ * hidden without disrupting running software.
+ *
+ * At the moment, we're running in an unknown context (WRT hiding -
+ * particularly if another fully fledged kernel ran before us) and
+ * depending on user settings, may elect to continue hiding them from
+ * native CPUID instructions.
+ *
+ * Xen doesn't use TSX itself, but use cpu_has_{hle,rtm} for various
+ * system reasons, mostly errata detection, so the meaning is more
+ * useful as "TSX infrastructure available", as opposed to "features
+ * advertised and working".
+ *
+ * Force the features to be visible in Xen's view if we see any of the
+ * infrastructure capable of hiding them.
+ */
+ if ( cpu_has_tsx_ctrl )
+ {
+ setup_force_cpu_cap(X86_FEATURE_HLE);
+ setup_force_cpu_cap(X86_FEATURE_RTM);
+ }
}
if ( cpu_has_tsx_ctrl )
@@ -53,9 +78,11 @@ void tsx_init(void)
rdmsrl(MSR_TSX_CTRL, val);
+ /* Check bottom bit only. Higher bits are various sentinels. */
+ rtm_disabled = !(opt_tsx & 1);
+
val &= ~(TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR);
- /* Check bottom bit only. Higher bits are various sentinals. */
- if ( !(opt_tsx & 1) )
+ if ( rtm_disabled )
val |= TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR;
wrmsrl(MSR_TSX_CTRL, val);
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 83143d4df8..bc4dc69253 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -627,6 +627,7 @@ static inline uint8_t get_cpu_family(uint32_t raw, uint8_t *model,
}
extern int8_t opt_tsx, cpu_has_tsx_ctrl;
+extern bool rtm_disabled;
void tsx_init(void);
enum ap_boot_method {
diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h
index c42f56bdd4..b65af42436 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -197,14 +197,14 @@ XEN_CPUFEATURE(FSGSBASE, 5*32+ 0) /*A {RD,WR}{FS,GS}BASE instructions */
XEN_CPUFEATURE(TSC_ADJUST, 5*32+ 1) /*S TSC_ADJUST MSR available */
XEN_CPUFEATURE(SGX, 5*32+ 2) /* Software Guard extensions */
XEN_CPUFEATURE(BMI1, 5*32+ 3) /*A 1st bit manipulation extensions */
-XEN_CPUFEATURE(HLE, 5*32+ 4) /*A Hardware Lock Elision */
+XEN_CPUFEATURE(HLE, 5*32+ 4) /*!a Hardware Lock Elision */
XEN_CPUFEATURE(AVX2, 5*32+ 5) /*A AVX2 instructions */
XEN_CPUFEATURE(FDP_EXCP_ONLY, 5*32+ 6) /*! x87 FDP only updated on exception. */
XEN_CPUFEATURE(SMEP, 5*32+ 7) /*S Supervisor Mode Execution Protection */
XEN_CPUFEATURE(BMI2, 5*32+ 8) /*A 2nd bit manipulation extensions */
XEN_CPUFEATURE(ERMS, 5*32+ 9) /*A Enhanced REP MOVSB/STOSB */
XEN_CPUFEATURE(INVPCID, 5*32+10) /*H Invalidate Process Context ID */
-XEN_CPUFEATURE(RTM, 5*32+11) /*A Restricted Transactional Memory */
+XEN_CPUFEATURE(RTM, 5*32+11) /*!A Restricted Transactional Memory */
XEN_CPUFEATURE(PQM, 5*32+12) /* Platform QoS Monitoring */
XEN_CPUFEATURE(NO_FPU_SEL, 5*32+13) /*! FPU CS/DS stored as zero */
XEN_CPUFEATURE(MPX, 5*32+14) /*s Memory Protection Extensions */