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,10 +1,29 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 #include <xen/cache.h>
 #include <xen/kernel.h>
+#include <xen/sched.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 = xmalloc(struct cpu_policy);
+
+    if ( !p )
+        return -ENOMEM;
+
+    *p = is_pv_domain(d) ? pv_max_cpu_policy : hvm_max_cpu_policy;
+
+    d->arch.cpu_policy = p;
+
+    recalculate_cpuid_policy(d);
+
+    return 0;
+}
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -779,22 +779,6 @@ void recalculate_cpuid_policy(struct dom
         p->extd.raw[0x1c] = EMPTY_LEAF;
 }
 
-int init_domain_cpuid_policy(struct domain *d)
-{
-    d->arch.cpuid = xmalloc(struct cpuid_policy);
-    d->arch.msr = xzalloc(struct msr_policy);
-
-    if ( !d->arch.cpuid || !d->arch.msr )
-        return -ENOMEM;
-
-    *d->arch.cpuid = is_pv_domain(d)
-        ? pv_max_cpu_policy : hvm_max_cpu_policy;
-
-    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
@@ -65,6 +65,7 @@
 #include <xen/numa.h>
 #include <xen/iommu.h>
 #include <compat/vcpu.h>
+#include <asm/cpu-policy.h>
 #include <asm/psr.h>
 #include <asm/spec_ctrl.h>
 #include <asm/shadow.h>
@@ -674,8 +675,7 @@ int arch_domain_create(struct domain *d,
     if ( is_idle_domain(d) )
     {
         d->arch.emulation_flags = 0;
-        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. */
     }
     else
     {
@@ -747,7 +747,7 @@ int arch_domain_create(struct domain *d,
             goto fail;
         paging_initialised = 1;
 
-        if ( (rc = init_domain_cpuid_policy(d)) )
+        if ( (rc = init_domain_cpu_policy(d)) )
             goto fail;
 
         d->arch.ioport_caps = 
@@ -857,8 +857,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.msr);
-    xfree(d->arch.cpuid);
+    XFREE(d->arch.cpu_policy);
     if ( paging_initialised )
         paging_final_teardown(d);
     free_perdomain_mappings(d);
@@ -878,8 +877,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/include/asm-x86/cpu-policy.h
+++ b/xen/include/asm-x86/cpu-policy.h
@@ -362,8 +362,13 @@ static inline void cpuid_featureset_to_p
     p->feat._7d1  = fs[FEATURESET_7d1];
 }
 
+struct domain;
+
 const uint32_t *lookup_deep_deps(uint32_t feature);
 
+/* 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
@@ -48,9 +48,6 @@ extern struct cpuidmasks cpuidmask_defau
 /* Whether or not cpuid faulting is available for the current domain. */
 DECLARE_PER_CPU(bool, cpuid_faulting_enabled);
 
-/* 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
@@ -399,9 +399,16 @@ struct arch_domain
      */
     uint8_t x87_fip_width;
 
-    /* CPUID Policy. */
-    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;
 
