File xsa435-0-22.patch of Package xen.32200
From 03812da3754d550dd8cbee7289469069ea6f0073 Mon Sep 17 00:00:00 2001
From: Andrew Cooper <andrew.cooper3@citrix.com>
Date: Tue, 28 Mar 2023 21:24:20 +0100
Subject: x86: Merge struct msr_policy into struct cpu_policy
As with the cpuid side, use a temporary define to make struct msr_policy still
work.
Note, this means that domains now have two separate struct cpu_policy
allocations with disjoint information, and system policies are in a similar
position, as well as xc_cpu_policy objects in libxenguest. All of these
duplications will be addressed in the following patches.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -33,7 +33,6 @@ enum {
};
#include <xen/lib/x86/cpu-policy.h>
-#include <xen/lib/x86/msr.h>
#define bitmaskof(idx) (1u << ((idx) & 31))
#define featureword_of(idx) ((idx) >> 5)
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -123,7 +123,7 @@ bool __init probe_cpuid_faulting(void)
int rc;
if ((rc = rdmsr_safe(MSR_INTEL_PLATFORM_INFO, val)) == 0)
- raw_msr_policy.plaform_info.cpuid_faulting =
+ raw_msr_policy.platform_info.cpuid_faulting =
val & MSR_PLATFORM_INFO_CPUID_FAULTING;
if (rc ||
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -56,7 +56,7 @@ static void __init calculate_host_policy
/* 0x000000ce MSR_INTEL_PLATFORM_INFO */
/* probe_cpuid_faulting() sanity checks presence of MISC_FEATURES_ENABLES */
- mp->plaform_info.cpuid_faulting = cpu_has_cpuid_faulting;
+ mp->platform_info.cpuid_faulting = cpu_has_cpuid_faulting;
/* Temporary, until we have known_features[] for feature bits in MSRs. */
mp->arch_caps.raw &=
@@ -78,7 +78,7 @@ static void __init calculate_hvm_max_pol
*mp = host_msr_policy;
/* It's always possible to emulate CPUID faulting for HVM guests */
- mp->plaform_info.cpuid_faulting = true;
+ mp->platform_info.cpuid_faulting = true;
mp->arch_caps.raw = 0; /* Not supported yet. */
}
@@ -111,7 +111,7 @@ int init_domain_msr_policy(struct domain
/* See comment in intel_ctxt_switch_levelling() */
if ( is_control_domain(d) )
- mp->plaform_info.cpuid_faulting = false;
+ mp->platform_info.cpuid_faulting = false;
/*
* Expose the "hardware speculation behaviour" bits of ARCH_CAPS to dom0,
@@ -223,7 +223,7 @@ int guest_rdmsr(const struct vcpu *v, ui
break;
case MSR_INTEL_PLATFORM_INFO:
- *val = mp->plaform_info.raw;
+ *val = mp->platform_info.raw;
break;
case MSR_ARCH_CAPABILITIES:
@@ -451,7 +451,7 @@ int guest_wrmsr(struct vcpu *v, uint32_t
bool old_cpuid_faulting = msrs->misc_features_enables.cpuid_faulting;
rsvd = ~0ull;
- if ( mp->plaform_info.cpuid_faulting )
+ if ( mp->platform_info.cpuid_faulting )
rsvd &= ~MSR_MISC_FEATURES_CPUID_FAULTING;
if ( val & rsvd )
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -8,8 +8,9 @@
#include <xen/types.h>
#include <xen/percpu.h>
#include <xen/errno.h>
+#include <xen/kernel.h>
-#include <xen/lib/x86/msr.h>
+#include <xen/lib/x86/cpu-policy.h>
#include <asm/asm_defns.h>
#include <asm/cpufeature.h>
--- a/xen/include/xen/lib/x86/cpu-policy.h
+++ b/xen/include/xen/lib/x86/cpu-policy.h
@@ -3,7 +3,6 @@
#define XEN_LIB_X86_POLICIES_H
#include <xen/lib/x86/cpuid-autogen.h>
-#include <xen/lib/x86/msr.h>
#define FEATURESET_1d 0 /* 0x00000001.edx */
#define FEATURESET_1c 1 /* 0x00000001.ecx */
@@ -95,6 +94,9 @@ static inline void cpuid_count_leaf(
CPUID_GUEST_NR_XSTATE - !!CPUID_GUEST_NR_XSTATE + \
CPUID_GUEST_NR_EXTD + 2 /* hv_limit and hv2_limit */ )
+/* Maximum number of MSRs written when serialising a cpu_policy. */
+#define MSR_MAX_SERIALISED_ENTRIES 2
+
struct cpu_policy
{
#define DECL_BITFIELD(word) _DECL_BITFIELD(FEATURESET_ ## word)
@@ -307,6 +309,44 @@ struct cpu_policy
};
} extd;
+ /*
+ * 0x000000ce - MSR_INTEL_PLATFORM_INFO
+ *
+ * This MSR is non-architectural, but for simplicy we allow it to be read
+ * unconditionally. CPUID Faulting support can be fully emulated for HVM
+ * guests so can be offered unconditionally, while support for PV guests
+ * is dependent on real hardware support.
+ */
+ union {
+ uint32_t raw;
+ struct {
+ uint32_t :31;
+ bool cpuid_faulting:1;
+ };
+ } platform_info;
+
+ /*
+ * 0x0000010a - MSR_ARCH_CAPABILITIES
+ *
+ * This is an Intel-only MSR, which provides miscellaneous enumeration,
+ * including those which indicate that microarchitectrual sidechannels are
+ * fixed in hardware.
+ */
+ union {
+ uint32_t raw;
+ struct {
+ bool rdcl_no:1;
+ bool ibrs_all:1;
+ bool rsba:1;
+ bool skip_l1dfl:1;
+ bool ssb_no:1;
+ bool mds_no:1;
+ bool if_pschange_mc_no:1;
+ bool tsx_ctrl:1;
+ bool taa_no:1;
+ };
+ } arch_caps;
+
#undef __DECL_BITFIELD
#undef _DECL_BITFIELD
#undef DECL_BITFIELD
@@ -320,6 +360,7 @@ struct cpu_policy
/* Temporary */
#define cpuid_policy cpu_policy
+#define msr_policy cpu_policy
struct old_cpu_policy
{
@@ -384,9 +425,11 @@ void x86_cpuid_policy_fill_native(struct
#ifdef __XEN__
#include <public/arch-x86/xen.h>
typedef XEN_GUEST_HANDLE_64(xen_cpuid_leaf_t) cpuid_leaf_buffer_t;
+typedef XEN_GUEST_HANDLE_64(xen_msr_entry_t) msr_entry_buffer_t;
#else
#include <xen/arch-x86/xen.h>
typedef xen_cpuid_leaf_t cpuid_leaf_buffer_t[];
+typedef xen_msr_entry_t msr_entry_buffer_t[];
#endif
/**
@@ -404,6 +447,21 @@ typedef xen_cpuid_leaf_t cpuid_leaf_buff
int x86_cpuid_copy_to_buffer(const struct cpuid_policy *policy,
cpuid_leaf_buffer_t leaves, uint32_t *nr_entries);
+/**
+ * Serialise an msr_policy object into an array.
+ *
+ * @param policy The msr_policy to serialise.
+ * @param msrs The array of msrs to serialise into.
+ * @param nr_entries The number of entries in 'msrs'.
+ * @returns -errno
+ *
+ * Writes at most MSR_MAX_SERIALISED_ENTRIES. May fail with -ENOBUFS if the
+ * buffer array is too short. On success, nr_entries is updated with the
+ * actual number of msrs written.
+ */
+int x86_msr_copy_to_buffer(const struct msr_policy *policy,
+ msr_entry_buffer_t msrs, uint32_t *nr_entries);
+
#endif /* !XEN_LIB_X86_POLICIES_H */
/*
--- a/xen/include/xen/lib/x86/msr.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Common data structures and functions consumed by hypervisor and toolstack */
-#ifndef XEN_LIB_X86_MSR_H
-#define XEN_LIB_X86_MSR_H
-
-/* Maximum number of MSRs written when serialising msr_policy. */
-#define MSR_MAX_SERIALISED_ENTRIES 2
-
-/* MSR policy object for shared per-domain MSRs */
-struct msr_policy
-{
- /*
- * 0x000000ce - MSR_INTEL_PLATFORM_INFO
- *
- * This MSR is non-architectural, but for simplicy we allow it to be read
- * unconditionally. CPUID Faulting support can be fully emulated for HVM
- * guests so can be offered unconditionally, while support for PV guests
- * is dependent on real hardware support.
- */
- union {
- uint32_t raw;
- struct {
- uint32_t :31;
- bool cpuid_faulting:1;
- };
- } plaform_info;
-
- /*
- * 0x0000010a - MSR_ARCH_CAPABILITIES
- *
- * This is an Intel-only MSR, which provides miscellaneous enumeration,
- * including those which indicate that microarchitectrual sidechannels are
- * fixed in hardware.
- */
- union {
- uint32_t raw;
- struct {
- bool rdcl_no:1;
- bool ibrs_all:1;
- bool rsba:1;
- bool skip_l1dfl:1;
- bool ssb_no:1;
- bool mds_no:1;
- bool if_pschange_mc_no:1;
- bool tsx_ctrl:1;
- bool taa_no:1;
- };
- } arch_caps;
-};
-
-#ifdef __XEN__
-#include <public/arch-x86/xen.h>
-typedef XEN_GUEST_HANDLE_64(xen_msr_entry_t) msr_entry_buffer_t;
-#else
-#include <xen/arch-x86/xen.h>
-typedef xen_msr_entry_t msr_entry_buffer_t[];
-#endif
-
-/**
- * Serialise an msr_policy object into an array.
- *
- * @param policy The msr_policy to serialise.
- * @param msrs The array of msrs to serialise into.
- * @param nr_entries The number of entries in 'msrs'.
- * @returns -errno
- *
- * Writes at most MSR_MAX_SERIALISED_ENTRIES. May fail with -ENOBUFS if the
- * buffer array is too short. On success, nr_entries is updated with the
- * actual number of msrs written.
- */
-int x86_msr_copy_to_buffer(const struct msr_policy *policy,
- msr_entry_buffer_t msrs, uint32_t *nr_entries);
-
-/**
- * Unserialise an msr_policy object from an array of msrs.
- *
- * @param policy The msr_policy object to unserialise into.
- * @param msrs The array of msrs to unserialise from.
- * @param nr_entries The number of entries in 'msrs'.
- * @param err_msr Optional hint filled on error.
- * @returns -errno
- *
- * Reads at most MSR_MAX_SERIALISED_ENTRIES. May fail for a number of reasons
- * based on the content in an individual 'msrs' entry, including the MSR index
- * not being valid in the policy, the flags field being nonzero, or if the
- * value provided would truncate when stored in the policy. In such cases,
- * the optional err_* pointer is filled in to aid diagnostics.
- *
- * No content validation is performed on the data stored in the policy object.
- */
-int x86_msr_copy_from_buffer(struct msr_policy *policy,
- const msr_entry_buffer_t msrs, uint32_t nr_entries,
- uint32_t *err_msr);
-
-#endif /* !XEN_LIB_X86_MSR_H */
-
-/*
- * Local variables:
- * mode: C
- * c-file-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */
--- a/xen/lib/x86/msr.c
+++ b/xen/lib/x86/msr.c
@@ -1,6 +1,6 @@
#include "private.h"
-#include <xen/lib/x86/msr.h>
+#include <xen/lib/x86/cpu-policy.h>
/*
* Copy a single MSR into the provided msr_entry_buffer_t buffer, performing a
@@ -38,7 +38,7 @@ int x86_msr_copy_to_buffer(const struct
return ret; \
})
- COPY_MSR(MSR_INTEL_PLATFORM_INFO, p->plaform_info.raw);
+ COPY_MSR(MSR_INTEL_PLATFORM_INFO, p->platform_info.raw);
COPY_MSR(MSR_ARCH_CAPABILITIES, p->arch_caps.raw);
#undef COPY_MSR
@@ -48,74 +48,6 @@ int x86_msr_copy_to_buffer(const struct
return 0;
}
-int x86_msr_copy_from_buffer(struct msr_policy *p,
- const msr_entry_buffer_t msrs, uint32_t nr_entries,
- uint32_t *err_msr)
-{
- unsigned int i;
- xen_msr_entry_t data;
- int rc;
-
- /*
- * A well formed caller is expected to pass an array with entries in
- * order, and without any repetitions. However, due to per-vendor
- * differences, and in the case of upgrade or levelled scenarios, we
- * typically expect fewer than MAX entries to be passed.
- *
- * Detecting repeated entries is prohibitively complicated, so we don't
- * bother. That said, one way or another if more than MAX entries are
- * passed, something is wrong.
- */
- if ( nr_entries > MSR_MAX_SERIALISED_ENTRIES )
- return -E2BIG;
-
- for ( i = 0; i < nr_entries; i++ )
- {
- if ( copy_from_buffer_offset(&data, msrs, i, 1) )
- return -EFAULT;
-
- if ( data.flags ) /* .flags MBZ */
- {
- rc = -EINVAL;
- goto err;
- }
-
- switch ( data.idx )
- {
- /*
- * Assign data.val to p->field, checking for truncation if the
- * backing storage for field is smaller than uint64_t
- */
-#define ASSIGN(field) \
-({ \
- if ( (typeof(p->field))data.val != data.val ) \
- { \
- rc = -EOVERFLOW; \
- goto err; \
- } \
- p->field = data.val; \
-})
-
- case MSR_INTEL_PLATFORM_INFO: ASSIGN(plaform_info.raw); break;
- case MSR_ARCH_CAPABILITIES: ASSIGN(arch_caps.raw); break;
-
-#undef ASSIGN
-
- default:
- rc = -ERANGE;
- goto err;
- }
- }
-
- return 0;
-
- err:
- if ( err_msr )
- *err_msr = data.idx;
-
- return rc;
-}
-
/*
* Local variables:
* mode: C