File xsa435-0-49.patch of Package xen.30332

# Commit 44fde35fdd5abb99a9d7de79ffe95176260b50fe
# Date 2023-08-03 19:14:19 +0100
# Author Roger Pau Monne <roger.pau@citrix.com>
# Committer Andrew Cooper <andrew.cooper3@citrix.com>
libs/guest: introduce support for setting guest MSRs

Like it's done with CPUID, introduce support for passing MSR values to
xc_cpuid_apply_policy().  The chosen format for expressing MSR policy
data matches the current one used for CPUID.  Note that existing
callers of xc_cpuid_apply_policy() can pass NULL as the value for the
newly introduced 'msr' parameter in order to preserve the same
functionality, and in fact that's done in libxl on this patch.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
(cherry picked from commit ed742cf1b65c822759833027ca5cbb087c506a41)

--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1802,6 +1802,7 @@ int xc_domain_debug_control(xc_interface
                             uint32_t vcpu);
 
 #if defined(__i386__) || defined(__x86_64__)
+#define XC_X86_MSR_LEAF XEN_X86_MSR_LEAF
 int xc_cpuid_set(xc_interface *xch,
                  uint32_t domid,
                  const unsigned int *input,
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -283,6 +283,25 @@ static void cpuid(const unsigned int *in
 #endif
 }
 
+static void msr(unsigned int input, unsigned int *regs,
+                const uint32_t *fs, unsigned int n)
+{
+    regs[0] = 0;
+    regs[1] = 0;
+    regs[2] = 0;
+    regs[3] = 0;
+
+    switch ( input )
+    {
+    case 0x10a: /* ARCH_CAPS */
+        if ( n > FEATURESET_m10Al )
+            regs[0] = fs[FEATURESET_m10Al];
+        if ( n > FEATURESET_m10Ah )
+            regs[3] = fs[FEATURESET_m10Ah];
+        break;
+    }
+}
+
 static int get_cpuid_domain_info(xc_interface *xch, uint32_t domid,
                                  struct cpuid_domain_info *info,
                                  uint32_t *featureset,
@@ -815,7 +834,10 @@ int xc_cpuid_apply_policy(xc_interface *
     input[1] = XEN_CPUID_INPUT_UNUSED;
     for ( ; ; )
     {
-        cpuid(input, regs);
+        if ( input[0] != XEN_X86_MSR_LEAF )
+            cpuid(input, regs);
+        else
+            msr(input[1], regs, info.featureset, info.nr_features);
         xc_cpuid_policy(&info, input, regs);
 
         if ( regs[0] || regs[1] || regs[2] || regs[3] )
@@ -843,6 +865,9 @@ int xc_cpuid_apply_policy(xc_interface *
                 continue;
         }
 
+        if ( input[0] == XEN_X86_MSR_LEAF )
+            break;
+
         input[0]++;
         if ( !(input[0] & 0x80000000u) && (input[0] > base_max ) )
             input[0] = 0x80000000u;
@@ -854,7 +879,10 @@ int xc_cpuid_apply_policy(xc_interface *
             input[1] = 1; /* Xen automatically calculates almost everything. */
 
         if ( (input[0] & 0x80000000u) && (input[0] > ext_max) )
-            break;
+        {
+            input[0] = XEN_X86_MSR_LEAF;
+            input[1] = 0x10a; /* ARCH_CAPS */
+        }
     }
 
  out:
@@ -895,7 +923,10 @@ int xc_cpuid_set(
     if ( rc )
         goto out;
 
-    cpuid(input, regs);
+    if ( input[0] != XC_X86_MSR_LEAF )
+        cpuid(input, regs);
+    else
+        msr(input[1], regs, info.featureset, info.nr_features);
 
     memcpy(polregs, regs, sizeof(regs));
     xc_cpuid_policy(&info, input, polregs);
openSUSE Build Service is sponsored by