[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] x86/tsx: Expose RTM_ALWAYS_ABORT to guests
commit c94e2105924347de0d9f32065370e802a20cc829 Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Sat Apr 6 20:36:54 2024 +0100 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Tue Apr 9 16:37:30 2024 +0100 x86/tsx: Expose RTM_ALWAYS_ABORT to guests A TSX Abort is one option mitigate Native-BHI, but a guest kernel doesn't get to see this if Xen has turned RTM off using MSR_TSX_{CTRL,FORCE_ABORT}. Therefore, the meaning of RTM_ALWAYS_ABORT has been adjusted to "XBEGIN won't fault", and it should be exposed to guests so they can make a better decision. Expose it in the max policy for any RTM-capable system. Offer it by default only if RTM has been disabled. Update test-tsx to account for this new meaning. While adjusting the logic in test_guest_policies(), take the opportunity to use feature names (now they're available) to make the logic easier to follow. This is part of XSA-456 / CVE-2024-2201. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- tools/tests/tsx/test-tsx.c | 39 +++++++++++++++++++---------- xen/arch/x86/cpu-policy.c | 20 +++++++++++++++ xen/include/public/arch-x86/cpufeatureset.h | 2 +- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/tools/tests/tsx/test-tsx.c b/tools/tests/tsx/test-tsx.c index b7e1972ce8..5af04953f3 100644 --- a/tools/tests/tsx/test-tsx.c +++ b/tools/tests/tsx/test-tsx.c @@ -311,25 +311,25 @@ static void test_guest_policies(const struct cpu_policy *max, dump_tsx_details(max, "Max:"); dump_tsx_details(def, "Def:"); - if ( ((max->feat.raw[0].d | def->feat.raw[0].d) & - (bitmaskof(X86_FEATURE_TSX_FORCE_ABORT) | - bitmaskof(X86_FEATURE_RTM_ALWAYS_ABORT) | - bitmaskof(X86_FEATURE_SRBDS_CTRL))) || - ((max->arch_caps.raw | def->arch_caps.raw) & ARCH_CAPS_TSX_CTRL) ) + if ( max->feat.tsx_force_abort || def->feat.tsx_force_abort || + max->feat.srbds_ctrl || def->feat.srbds_ctrl || + max->arch_caps.tsx_ctrl || def->arch_caps.tsx_ctrl ) fail(" Xen-only TSX controls offered to guest\n"); switch ( rtm_behaviour ) { case RTM_UD: - if ( (max->feat.raw[0].b | def->feat.raw[0].b) & - (bitmaskof(X86_FEATURE_HLE) | bitmaskof(X86_FEATURE_RTM)) ) - fail(" HLE/RTM offered to guests despite not being available\n"); + if ( max->feat.hle || def->feat.hle || + max->feat.rtm || def->feat.rtm || + max->feat.rtm_always_abort || def->feat.rtm_always_abort ) + fail(" HLE/RTM/RTM_AA offered to guests despite not being available\n"); break; case RTM_ABORT: - if ( def->feat.raw[0].b & - (bitmaskof(X86_FEATURE_HLE) | bitmaskof(X86_FEATURE_RTM)) ) + if ( def->feat.hle || def->feat.rtm ) fail(" HLE/RTM offered to guests by default despite not being usable\n"); + if ( !def->feat.rtm_always_abort ) + fail(" RTM_AA not offered to guests by default despite being available\n"); break; case RTM_OK: @@ -340,6 +340,9 @@ static void test_guest_policies(const struct cpu_policy *max, if ( def->feat.hle ) fail(" Fail: HLE offered in default policy\n"); + + if ( def->feat.rtm && def->feat.rtm_always_abort ) + fail(" Fail: Both RTM and RTM_AA offered in default policy\n"); } static void test_def_max_policies(void) @@ -388,14 +391,13 @@ static void test_guest(struct xen_domctl_createdomain *c) if ( guest_policy.policy.feat.hle || guest_policy.policy.feat.tsx_force_abort || - guest_policy.policy.feat.rtm_always_abort || guest_policy.policy.feat.srbds_ctrl || guest_policy.policy.arch_caps.tsx_ctrl ) fail(" Unexpected features advertised\n"); if ( host.policy.feat.rtm ) { - unsigned int _7b0; + unsigned int _7b0, _7d0; /* * If host RTM is available, all combinations of guest flags should be @@ -403,6 +405,8 @@ static void test_guest(struct xen_domctl_createdomain *c) */ _7b0 = (guest_policy.policy.feat.raw[0].b ^= (bitmaskof(X86_FEATURE_HLE) | bitmaskof(X86_FEATURE_RTM))); + _7d0 = (guest_policy.policy.feat.raw[0].d ^= + bitmaskof(X86_FEATURE_RTM_ALWAYS_ABORT)); /* Set the new policy. */ rc = xc_cpu_policy_set_domain(xch, domid, &guest_policy); @@ -426,10 +430,17 @@ static void test_guest(struct xen_domctl_createdomain *c) if ( guest_policy.policy.feat.raw[0].b != _7b0 ) { - fail(" Expected CPUID.7[1].b 0x%08x differs from actual 0x%08x\n", + fail(" Expected CPUID.7[0].b 0x%08x differs from actual 0x%08x\n", _7b0, guest_policy.policy.feat.raw[0].b); goto out; } + + if ( guest_policy.policy.feat.raw[0].d != _7d0 ) + { + fail(" Expected CPUID.7[0].d 0x%08x differs from actual 0x%08x\n", + _7d0, guest_policy.policy.feat.raw[0].d); + goto out; + } } out: @@ -514,6 +525,8 @@ static void test_tsx(void) i, errno, strerror(errno)); } + dump_tsx_details(&host.policy, "Host:"); + rc = xc_physinfo(xch, &physinfo); if ( rc ) return fail("Failed to obtain physinfo: %d - %s\n", diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c index 5952ff20e6..4b6d962763 100644 --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -462,6 +462,21 @@ static void __init guest_common_max_feature_adjustments(uint32_t *fs) */ __set_bit(X86_FEATURE_HTT, fs); __set_bit(X86_FEATURE_CMP_LEGACY, fs); + + /* + * To mitigate Native-BHI, one option is to use a TSX Abort on capable + * systems. This is safe even if RTM has been disabled for other reasons + * via MSR_TSX_{CTRL,FORCE_ABORT}. However, a guest kernel doesn't get to + * know this type of information. + * + * Therefore the meaning of RTM_ALWAYS_ABORT has been adjusted, to instead + * mean "XBEGIN won't fault". This is enough for a guest kernel to make + * an informed choice WRT mitigating Native-BHI. + * + * If RTM-capable, we can run a VM which has seen RTM_ALWAYS_ABORT. + */ + if ( test_bit(X86_FEATURE_RTM, fs) ) + __set_bit(X86_FEATURE_RTM_ALWAYS_ABORT, fs); } static void __init guest_common_default_feature_adjustments(uint32_t *fs) @@ -534,9 +549,14 @@ static void __init guest_common_default_feature_adjustments(uint32_t *fs) * function as expected, but is technically compatible with the ISA. * * Do not advertise RTM to guests by default if it won't actually work. + * Instead, advertise RTM_ALWAYS_ABORT indicating that TSX Aborts are safe + * to use, e.g. for mitigating Native-BHI. */ if ( rtm_disabled ) + { __clear_bit(X86_FEATURE_RTM, fs); + __set_bit(X86_FEATURE_RTM_ALWAYS_ABORT, fs); + } } static void __init guest_common_feature_adjustments(uint32_t *fs) diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/public/arch-x86/cpufeatureset.h index 6bb1ee3b0a..53f13dec31 100644 --- a/xen/include/public/arch-x86/cpufeatureset.h +++ b/xen/include/public/arch-x86/cpufeatureset.h @@ -264,7 +264,7 @@ XEN_CPUFEATURE(FSRM, 9*32+ 4) /*A Fast Short REP MOVS */ XEN_CPUFEATURE(AVX512_VP2INTERSECT, 9*32+8) /*a VP2INTERSECT{D,Q} insns */ XEN_CPUFEATURE(SRBDS_CTRL, 9*32+ 9) /* MSR_MCU_OPT_CTRL and RNGDS_MITG_DIS. */ XEN_CPUFEATURE(MD_CLEAR, 9*32+10) /*!A VERW clears microarchitectural buffers */ -XEN_CPUFEATURE(RTM_ALWAYS_ABORT, 9*32+11) /*! June 2021 TSX defeaturing in microcode. */ +XEN_CPUFEATURE(RTM_ALWAYS_ABORT, 9*32+11) /*! RTM disabled (but XBEGIN wont fault) */ XEN_CPUFEATURE(TSX_FORCE_ABORT, 9*32+13) /* MSR_TSX_FORCE_ABORT.RTM_ABORT */ XEN_CPUFEATURE(SERIALIZE, 9*32+14) /*A SERIALIZE insn */ XEN_CPUFEATURE(HYBRID, 9*32+15) /* Heterogeneous platform */ -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |