[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 05/27] x86/cpuid: Allocate a CPUID policy for every domain



Introduce init_domain_cpuid_policy() to allocate an appropriate cpuid policy
for the domain (currently the domains maximum applicable policy), and call it
during domain construction.

init_guest_cpuid() now needs calling before dom0 is constructed.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
---
 xen/arch/x86/cpuid.c         | 12 ++++++++++++
 xen/arch/x86/domain.c        |  6 ++++++
 xen/arch/x86/setup.c         |  4 ++--
 xen/include/asm-x86/cpuid.h  | 13 +++++++++++++
 xen/include/asm-x86/domain.h |  3 +++
 5 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 92e825e..e7bb0d5 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -258,6 +258,18 @@ const uint32_t * __init lookup_deep_deps(uint32_t feature)
     return NULL;
 }
 
+int init_domain_cpuid_policy(struct domain *d)
+{
+    d->arch.cpuid = xmalloc(struct cpuid_policy);
+
+    if ( !d->arch.cpuid )
+        return -ENOMEM;
+
+    *d->arch.cpuid = is_pv_domain(d) ? pv_max_policy : hvm_max_policy;
+
+    return 0;
+}
+
 void guest_cpuid(const struct vcpu *v, unsigned int leaf,
                  unsigned int subleaf, struct cpuid_leaf *res)
 {
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 11fa379..3082a6c 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -563,6 +563,7 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
     if ( is_idle_domain(d) )
     {
         d->arch.emulation_flags = 0;
+        d->arch.cpuid = ZERO_BLOCK_PTR; /* Catch stray misuses. */
     }
     else
     {
@@ -632,6 +633,9 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
             goto fail;
         paging_initialised = 1;
 
+        if ( (rc = init_domain_cpuid_policy(d)) )
+            goto fail;
+
         d->arch.cpuids = xmalloc_array(cpuid_input_t, MAX_CPUID_INPUT);
         rc = -ENOMEM;
         if ( d->arch.cpuids == NULL )
@@ -705,6 +709,7 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags,
     cleanup_domain_irq_mapping(d);
     free_xenheap_page(d->shared_info);
     xfree(d->arch.cpuids);
+    xfree(d->arch.cpuid);
     if ( paging_initialised )
         paging_final_teardown(d);
     free_perdomain_mappings(d);
@@ -723,6 +728,7 @@ void arch_domain_destroy(struct domain *d)
 
     xfree(d->arch.e820);
     xfree(d->arch.cpuids);
+    xfree(d->arch.cpuid);
 
     free_domain_pirqs(d);
     if ( !is_idle_domain(d) )
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 94db514..0ccef1d 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1540,6 +1540,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( !tboot_protect_mem_regions() )
         panic("Could not protect TXT memory regions");
 
+    init_guest_cpuid();
+
     if ( opt_dom0pvh )
         domcr_flags |= DOMCRF_pvh | DOMCRF_hap;
 
@@ -1590,8 +1592,6 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                "Multiple initrd candidates, picking module #%u\n",
                initrdidx);
 
-    init_guest_cpuid();
-
     /*
      * Temporarily clear SMAP in CR4 to allow user-accesses in 
construct_dom0().
      * This saves a large number of corner cases interactions with
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index b67c10e..86fa0b1 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -84,6 +84,16 @@ struct cpuid_policy
      * - Guest appropriate:
      *   - All FEATURESET_* words
      *
+     * Per-domain objects:
+     *
+     * - Host accurate:
+     *   - max_{,sub}leaf
+     *   - {xcr0,xss}_{high,low}
+     *   - All FEATURESET_* words
+     *
+     * - Guest accurate:
+     *   - Nothing
+     *
      * Everything else should be considered inaccurate, and not necesserily 0.
      */
 
@@ -203,6 +213,9 @@ extern struct cpuid_policy raw_policy, host_policy, 
pv_max_policy,
 #define pv_featureset pv_max_policy.fs
 #define hvm_featureset hvm_max_policy.fs
 
+/* Allocate and initialise a CPUID policy suitable for the domain. */
+int init_domain_cpuid_policy(struct domain *d);
+
 void guest_cpuid(const struct vcpu *v, unsigned int leaf,
                  unsigned int subleaf, struct cpuid_leaf *res);
 
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 95762cf..d2e087f 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -340,6 +340,9 @@ struct arch_domain
     /* Is PHYSDEVOP_eoi to automatically unmask the event channel? */
     bool_t auto_unmask;
 
+    /* CPUID Policy. */
+    struct cpuid_policy *cpuid;
+
     /* Values snooped from updates to cpuids[] (below). */
     u8 x86;                  /* CPU family */
     u8 x86_vendor;           /* CPU vendor */
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.