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);