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 )
openSUSE Build Service is sponsored by