diff options
-rw-r--r-- | tools/libs/guest/xg_cpuid_x86.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/cpuid.c | 24 | ||||
-rw-r--r-- | xen/arch/x86/spec_ctrl.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/tsx.c | 31 | ||||
-rw-r--r-- | xen/include/asm-x86/processor.h | 1 | ||||
-rw-r--r-- | xen/include/public/arch-x86/cpufeatureset.h | 4 |
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 */ |