File xsa435-0-24.patch of Package xen.32200
From bd13dae34809e61e37ba1cd5de893c5c10c46256 Mon Sep 17 00:00:00 2001
From: Andrew Cooper <andrew.cooper3@citrix.com>
Date: Wed, 29 Mar 2023 11:32:25 +0100
Subject: x86: Merge a domain's {cpuid,msr} policy objects
Right now, they're the same underlying type, containing disjoint information.
Drop the d->arch.msr pointer, and union d->arch.cpuid to give it a second name
of cpu_policy in the interim.
Merge init_domain_{cpuid,msr}_policy() into a single init_domain_cpu_policy(),
moving the implementation into cpu-policy.c
No practical change. This undoes the transient doubling of storage space from
earlier patches.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/cpu-policy.c
+++ b/xen/arch/x86/cpu-policy.c
@@ -1,12 +1,54 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <xen/cache.h>
#include <xen/kernel.h>
+#include <xen/sched.h>
#include <xen/lib/x86/cpu-policy.h>
#include <asm/cpu-policy.h>
+#include <asm/msr-index.h>
+#include <asm/setup.h>
struct cpu_policy __read_mostly raw_cpu_policy;
struct cpu_policy __read_mostly host_cpu_policy;
struct cpu_policy __read_mostly pv_max_cpu_policy;
struct cpu_policy __read_mostly hvm_max_cpu_policy;
+
+int init_domain_cpu_policy(struct domain *d)
+{
+ struct cpu_policy *p =
+ xmemdup(is_pv_domain(d) ? &pv_max_cpu_policy
+ : &hvm_max_cpu_policy);
+
+ if ( !p )
+ return -ENOMEM;
+
+ /* See comment in intel_ctxt_switch_levelling() */
+ if ( is_control_domain(d) )
+ p->platform_info.cpuid_faulting = false;
+
+ /*
+ * Expose the "hardware speculation behaviour" bits of ARCH_CAPS to dom0,
+ * so dom0 can turn off workarounds as appropriate. Temporary, until the
+ * domain policy logic gains a better understanding of MSRs.
+ */
+ if ( is_hardware_domain(d) && cpu_has_arch_caps )
+ {
+ uint64_t val;
+
+ rdmsrl(MSR_ARCH_CAPABILITIES, val);
+
+ p->arch_caps.raw = val &
+ (ARCH_CAPS_RDCL_NO | ARCH_CAPS_IBRS_ALL | ARCH_CAPS_RSBA |
+ ARCH_CAPS_SSB_NO | ARCH_CAPS_MDS_NO | ARCH_CAPS_IF_PSCHANGE_MC_NO |
+ ARCH_CAPS_TAA_NO | ARCH_CAPS_SBDR_SSDP_NO | ARCH_CAPS_FBSDP_NO |
+ ARCH_CAPS_PSDP_NO | ARCH_CAPS_FB_CLEAR | ARCH_CAPS_RRSBA |
+ ARCH_CAPS_BHI_NO | ARCH_CAPS_PBRSB_NO);
+ }
+
+ d->arch.cpu_policy = p;
+
+ recalculate_cpuid_policy(d);
+
+ return 0;
+}
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -676,22 +676,6 @@ void recalculate_cpuid_policy(struct dom
p->extd.raw[0x1c] = EMPTY_LEAF;
}
-int init_domain_cpuid_policy(struct domain *d)
-{
- struct cpuid_policy *p =
- xmemdup(is_pv_domain(d) ? &pv_max_cpu_policy
- : &hvm_max_cpu_policy);
-
- if ( !p )
- return -ENOMEM;
-
- d->arch.cpuid = p;
-
- recalculate_cpuid_policy(d);
-
- return 0;
-}
-
void __init init_dom0_cpuid_policy(struct domain *d)
{
struct cpuid_policy *p = d->arch.cpuid;
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -64,6 +64,7 @@
#include <xen/numa.h>
#include <xen/iommu.h>
#include <compat/vcpu.h>
+#include <asm/cpu-policy.h>
#include <asm/psr.h>
#include <asm/pv/domain.h>
#include <asm/pv/mm.h>
@@ -483,8 +484,7 @@ int arch_domain_create(struct domain *d,
d->arch.ctxt_switch = &idle_csw;
- d->arch.cpuid = ZERO_BLOCK_PTR; /* Catch stray misuses. */
- d->arch.msr = ZERO_BLOCK_PTR;
+ d->arch.cpu_policy = ZERO_BLOCK_PTR; /* Catch stray misuses. */
return 0;
}
@@ -544,10 +544,7 @@ int arch_domain_create(struct domain *d,
goto fail;
paging_initialised = true;
- if ( (rc = init_domain_cpuid_policy(d)) )
- goto fail;
-
- if ( (rc = init_domain_msr_policy(d)) )
+ if ( (rc = init_domain_cpu_policy(d)) )
goto fail;
d->arch.ioport_caps =
@@ -614,8 +611,7 @@ int arch_domain_create(struct domain *d,
iommu_domain_destroy(d);
cleanup_domain_irq_mapping(d);
free_xenheap_page(d->shared_info);
- xfree(d->arch.cpuid);
- xfree(d->arch.msr);
+ XFREE(d->arch.cpu_policy);
if ( paging_initialised )
paging_final_teardown(d);
free_perdomain_mappings(d);
@@ -629,8 +625,7 @@ void arch_domain_destroy(struct domain *
hvm_domain_destroy(d);
xfree(d->arch.e820);
- xfree(d->arch.cpuid);
- xfree(d->arch.msr);
+ XFREE(d->arch.cpu_policy);
free_domain_pirqs(d);
if ( !is_idle_domain(d) )
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1534,7 +1534,7 @@ long arch_do_domctl(
if ( guest_handle_is_null(domctl->u.cpu_policy.leaves) )
domctl->u.cpu_policy.nr_leaves = CPUID_MAX_SERIALISED_LEAVES;
else if ( (ret = x86_cpuid_copy_to_buffer(
- d->arch.cpuid,
+ d->arch.cpu_policy,
domctl->u.cpu_policy.leaves,
&domctl->u.cpu_policy.nr_leaves)) )
break;
@@ -1543,7 +1543,7 @@ long arch_do_domctl(
if ( guest_handle_is_null(domctl->u.cpu_policy.msrs) )
domctl->u.cpu_policy.nr_msrs = MSR_MAX_SERIALISED_ENTRIES;
else if ( (ret = x86_msr_copy_to_buffer(
- d->arch.msr,
+ d->arch.cpu_policy,
domctl->u.cpu_policy.msrs,
&domctl->u.cpu_policy.nr_msrs)) )
break;
--- a/xen/arch/x86/msr.c
+++ b/xen/arch/x86/msr.c
@@ -96,43 +96,6 @@ void __init init_guest_msr_policy(void)
calculate_pv_max_policy();
}
-int init_domain_msr_policy(struct domain *d)
-{
- struct msr_policy *mp =
- xmemdup(is_pv_domain(d) ? &pv_max_cpu_policy
- : &hvm_max_cpu_policy);
-
- if ( !mp )
- return -ENOMEM;
-
- /* See comment in intel_ctxt_switch_levelling() */
- if ( is_control_domain(d) )
- mp->platform_info.cpuid_faulting = false;
-
- /*
- * Expose the "hardware speculation behaviour" bits of ARCH_CAPS to dom0,
- * so dom0 can turn off workarounds as appropriate. Temporary, until the
- * domain policy logic gains a better understanding of MSRs.
- */
- if ( is_hardware_domain(d) && boot_cpu_has(X86_FEATURE_ARCH_CAPS) )
- {
- uint64_t val;
-
- rdmsrl(MSR_ARCH_CAPABILITIES, val);
-
- mp->arch_caps.raw = val &
- (ARCH_CAPS_RDCL_NO | ARCH_CAPS_IBRS_ALL | ARCH_CAPS_RSBA |
- ARCH_CAPS_SSB_NO | ARCH_CAPS_MDS_NO | ARCH_CAPS_IF_PSCHANGE_MC_NO |
- ARCH_CAPS_TAA_NO | ARCH_CAPS_SBDR_SSDP_NO | ARCH_CAPS_FBSDP_NO |
- ARCH_CAPS_PSDP_NO | ARCH_CAPS_FB_CLEAR | ARCH_CAPS_RRSBA |
- ARCH_CAPS_BHI_NO | ARCH_CAPS_PBRSB_NO);
- }
-
- d->arch.msr = mp;
-
- return 0;
-}
-
int init_vcpu_msr_policy(struct vcpu *v)
{
struct domain *d = v->domain;
--- a/xen/include/asm-x86/cpu-policy.h
+++ b/xen/include/asm-x86/cpu-policy.h
@@ -3,10 +3,14 @@
#define X86_CPU_POLICY_H
struct cpu_policy;
+struct domain;
extern struct cpu_policy raw_cpu_policy;
extern struct cpu_policy host_cpu_policy;
extern struct cpu_policy pv_max_cpu_policy;
extern struct cpu_policy hvm_max_cpu_policy;
+/* Allocate and initialise a CPU policy suitable for the domain. */
+int init_domain_cpu_policy(struct domain *d);
+
#endif /* X86_CPU_POLICY_H */
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -49,9 +49,6 @@ extern struct cpuidmasks cpuidmask_defau
/* Check that all previously present features are still available. */
bool recheck_cpu_features(unsigned int cpu);
-/* Allocate and initialise a CPUID policy suitable for the domain. */
-int init_domain_cpuid_policy(struct domain *d);
-
/* Apply dom0-specific tweaks to the CPUID policy. */
void init_dom0_cpuid_policy(struct domain *d);
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -364,9 +364,16 @@ struct arch_domain
*/
uint8_t x87_fip_width;
- /* CPUID and MSR policy objects. */
- struct cpuid_policy *cpuid;
- struct msr_policy *msr;
+ /*
+ * The domain's CPU Policy. "cpu_policy" is considered the canonical
+ * pointer, but the "cpuid" and "msr" aliases exist so the most
+ * appropriate one can be used for local code clarity.
+ */
+ union {
+ struct cpu_policy *cpu_policy;
+ struct cpu_policy *cpuid;
+ struct cpu_policy *msr;
+ };
struct PITState vpit;
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -314,7 +314,6 @@ struct vcpu_msrs
};
void init_guest_msr_policy(void);
-int init_domain_msr_policy(struct domain *d);
int init_vcpu_msr_policy(struct vcpu *v);
/*