File xsa435-0-54.patch of Package xen.30332
From: Andrew Cooper <andrew.cooper3@citrix.com>
Origin: https://github.com/xenserver/xen.pg/blob/XS-8.3.x/patches/max-featureset-compat.patch
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -43,6 +43,28 @@ enum {
#define DEF_MAX_INTELEXT 0x80000008u
#define DEF_MAX_AMDEXT 0x8000001cu
+enum vendor {
+ VENDOR_UNKNOWN,
+ VENDOR_INTEL,
+ VENDOR_AMD,
+};
+
+static enum vendor lookup_vendor(unsigned int ebx, unsigned int ecx,
+ unsigned int edx)
+{
+ if ( ebx == 0x756e6547U && /* "GenuineIntel" */
+ ecx == 0x6c65746eU &&
+ edx == 0x49656e69U )
+ return VENDOR_INTEL;
+
+ if ( ebx == 0x68747541U && /* "AuthenticAMD" */
+ ecx == 0x444d4163U &&
+ edx == 0x69746e65U )
+ return VENDOR_AMD;
+
+ return VENDOR_UNKNOWN;
+}
+
int xc_get_cpu_levelling_caps(xc_interface *xch, uint32_t *caps)
{
DECLARE_SYSCTL;
@@ -57,8 +79,8 @@ int xc_get_cpu_levelling_caps(xc_interfa
return ret;
}
-int xc_get_cpu_featureset(xc_interface *xch, uint32_t index,
- uint32_t *nr_features, uint32_t *featureset)
+static int xc_get_cpu_featureset_(xc_interface *xch, uint32_t index,
+ uint32_t *nr_features, uint32_t *featureset)
{
DECLARE_SYSCTL;
DECLARE_HYPERCALL_BOUNCE(featureset,
@@ -84,6 +106,127 @@ int xc_get_cpu_featureset(xc_interface *
return ret;
}
+int xc_get_cpu_featureset(xc_interface *xch, uint32_t index,
+ uint32_t *nr, uint32_t *fs)
+{
+ uint32_t raw_fs[FEATURESET_NR_ENTRIES] = {}, raw_nr = ARRAY_SIZE(raw_fs);
+ uint32_t host_fs[FEATURESET_NR_ENTRIES] = {}, host_nr = ARRAY_SIZE(host_fs);
+ unsigned int vendor;
+ int ret;
+
+ if ( index != XEN_SYSCTL_cpu_featureset_pv_max &&
+ index != XEN_SYSCTL_cpu_featureset_hvm_max )
+ return xc_get_cpu_featureset_(xch, index, nr, fs);
+
+ /*
+ * Fake up a *_max featureset. Obtain the raw, host, and pv/hvm default.
+ *
+ * This is used by xenopsd to pass to the toolstack of the incoming
+ * domain, to allow it to establish migration safety.
+ */
+ ret = xc_get_cpu_featureset_(
+ xch, XEN_SYSCTL_cpu_featureset_raw, &raw_nr, raw_fs);
+ if ( ret && errno != ENOBUFS )
+ return ret;
+
+ ret = xc_get_cpu_featureset_(
+ xch, XEN_SYSCTL_cpu_featureset_host, &host_nr, host_fs);
+ if ( ret && errno != ENOBUFS )
+ return ret;
+
+ ret = xc_get_cpu_featureset_(xch, index, nr, fs);
+ if ( ret )
+ return ret;
+
+ /*
+ * Advertise HTT, x2APIC and CMP_LEGACY. They all impact topology,
+ * unconditionally leak into PV guests, and are fully emulated for HVM.
+ */
+ set_bit(X86_FEATURE_HTT, fs);
+ set_bit(X86_FEATURE_X2APIC, fs);
+ set_bit(X86_FEATURE_CMP_LEGACY, fs);
+
+ /*
+ * Feed HLE/RTM in from the host policy. We can safely migrate in VMs
+ * which saw HLE/RTM, even if the RTM is disabled for errata/security
+ * reasons.
+ */
+ clear_bit(X86_FEATURE_HLE, fs);
+ if ( test_bit(X86_FEATURE_HLE, host_fs) )
+ set_bit(X86_FEATURE_HLE, fs);
+
+ clear_bit(X86_FEATURE_RTM, fs);
+ if ( test_bit(X86_FEATURE_RTM, host_fs) )
+ set_bit(X86_FEATURE_RTM, fs);
+
+ /*
+ * The Gather Data Sampling microcode mitigation (August 2023) has an
+ * adverse performance impact on the CLWB instruction on SKX/CLX/CPX.
+ *
+ * We hid CLWB in the host policy to stop Xen using it, but VMs which
+ * have previously seen the CLWB feature can safely run on this CPU.
+ */
+ if ( test_bit(X86_FEATURE_CLWB, raw_fs) &&
+ !test_bit(X86_FEATURE_CLWB, host_fs) )
+ set_bit(X86_FEATURE_CLWB, fs);
+
+ /* if ( index == XEN_SYSCTL_cpu_featureset_hvm_max ) */
+ {
+ struct cpuid_leaf l;
+
+ cpuid_leaf(0, &l);
+ vendor = lookup_vendor(l.b, l.c, l.d);
+
+ /*
+ * MPX has been removed from newer Intel hardware. Therefore, we hide
+ * it by default, but can still accept any VMs which saw it, if
+ * hardware is MPX-capable.
+ */
+ if ( index == XEN_SYSCTL_cpu_featureset_hvm_max &&
+ test_bit(X86_FEATURE_MPX, host_fs) )
+ set_bit(X86_FEATURE_MPX, fs);
+
+ switch ( vendor )
+ {
+ case VENDOR_AMD:
+ /*
+ * In order to mitigate Spectre, AMD dropped the LWP feature in
+ * microcode, to make space for MSR_PRED_CMD. No one used LWP, but it
+ * was visible to guests at the time.
+ */
+ if ( index == XEN_SYSCTL_cpu_featureset_hvm_max )
+ set_bit(X86_FEATURE_LWP, fs);
+ break;
+
+ case VENDOR_INTEL:
+ /*
+ * MSR_ARCH_CAPS is just feature data, and we can offer it to guests
+ * unconditionally, although limit it to Intel systems as it is highly
+ * uarch-specific.
+ *
+ * In particular, the RSBA and RRSBA bits mean "you might migrate to a
+ * system where RSB underflow uses alternative predictors (a.k.a
+ * Retpoline not safe)", so these need to be visible to a guest in all
+ * cases, even when it's only some other server in the pool which
+ * suffers the identified behaviour.
+ *
+ * We can always run any VM which has previously (or will
+ * subsequently) run on hardware where Retpoline is not safe.
+ * Note:
+ * - The dependency logic may hide RRSBA for other reasons.
+ * - The max policy does not constitute a sensible configuration to
+ * run a guest in.
+ */
+ set_bit(X86_FEATURE_ARCH_CAPS, fs);
+ set_bit(X86_FEATURE_RSBA, fs);
+ set_bit(X86_FEATURE_RRSBA, fs);
+ break;
+ }
+ }
+
+ return 0;
+}
+
uint32_t xc_get_cpu_featureset_size(void)
{
return FEATURESET_NR_ENTRIES;
@@ -228,12 +371,7 @@ int xc_get_domain_cpu_policy(xc_interfac
struct cpuid_domain_info
{
- enum
- {
- VENDOR_UNKNOWN,
- VENDOR_INTEL,
- VENDOR_AMD,
- } vendor;
+ enum vendor vendor;
bool hvm;
uint64_t xfeature_mask;
@@ -314,16 +452,7 @@ static int get_cpuid_domain_info(xc_inte
int rc;
cpuid(in, regs);
- if ( regs[1] == 0x756e6547U && /* "GenuineIntel" */
- regs[2] == 0x6c65746eU &&
- regs[3] == 0x49656e69U )
- info->vendor = VENDOR_INTEL;
- else if ( regs[1] == 0x68747541U && /* "AuthenticAMD" */
- regs[2] == 0x444d4163U &&
- regs[3] == 0x69746e65U )
- info->vendor = VENDOR_AMD;
- else
- info->vendor = VENDOR_UNKNOWN;
+ info->vendor = lookup_vendor(regs[1], regs[2], regs[3]);
if ( xc_domain_getinfo(xch, domid, 1, &di) != 1 ||
di.domid != domid )