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:
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)
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
*/
_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);
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:
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",
raw_cpu_policy.feat.clwb )
__set_bit(X86_FEATURE_CLWB, 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)
* 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)
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 */