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

[Xen-devel] [PATCH 3/6] x86/cpuid: Handle leaf 0 in guest_cpuid()



Calculate a domains x86_vendor early in recalculate_cpuid_policy(); subsequent
patches need to make other recalculation decisions based on it.

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

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 076fab3..85c829d 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -355,6 +355,9 @@ void recalculate_cpuid_policy(struct domain *d)
     uint32_t fs[FSCAPINTS], max_fs[FSCAPINTS];
     unsigned int i;
 
+    p->x86_vendor = get_cpu_vendor(p->basic.vendor_ebx, p->basic.vendor_ecx,
+                                   p->basic.vendor_edx, gcv_guest);
+
     p->basic.max_leaf   = min(p->basic.max_leaf,   max->basic.max_leaf);
     p->feat.max_subleaf = min(p->feat.max_subleaf, max->feat.max_subleaf);
     p->extd.max_leaf    = min(p->extd.max_leaf,    max->extd.max_leaf);
@@ -677,6 +680,7 @@ static void pv_cpuid(uint32_t leaf, uint32_t subleaf, 
struct cpuid_leaf *res)
         *res = EMPTY_LEAF;
         break;
 
+    case 0x0:
     case 0x7:
     case XSTATE_CPUID:
         ASSERT_UNREACHABLE();
@@ -825,6 +829,7 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf, 
struct cpuid_leaf *res)
             res->a = 0;
         break;
 
+    case 0x0:
     case 0x7:
     case XSTATE_CPUID:
         ASSERT_UNREACHABLE();
@@ -850,7 +855,9 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
     switch ( leaf )
     {
     case 0 ... CPUID_GUEST_NR_BASIC - 1:
-        if ( leaf > p->basic.max_leaf )
+        ASSERT(p->basic.max_leaf < ARRAY_SIZE(p->basic.raw));
+        if ( leaf > min_t(uint32_t, p->basic.max_leaf,
+                          ARRAY_SIZE(p->basic.raw) - 1) )
             return;
 
         switch ( leaf )
@@ -873,6 +880,10 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
 
         default:
             goto legacy;
+
+        case 0x0:
+            *res = p->basic.raw[leaf];
+            break;
         }
         break;
 
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index a3f51f3..8e5259f 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -92,7 +92,7 @@ static int update_domain_cpuid_info(struct domain *d,
 {
     struct cpuid_policy *p = d->arch.cpuid;
     const struct cpuid_leaf leaf = { ctl->eax, ctl->ebx, ctl->ecx, ctl->edx };
-    int rc;
+    int rc, old_vendor = p->x86_vendor;
 
     /*
      * Skip update for leaves we don't care about.  This avoids the overhead
@@ -155,11 +155,7 @@ static int update_domain_cpuid_info(struct domain *d,
 
     switch ( ctl->input[0] )
     {
-    case 0: {
-        int old_vendor = p->x86_vendor;
-
-        p->x86_vendor = get_cpu_vendor(ctl->ebx, ctl->ecx, ctl->edx, 
gcv_guest);
-
+    case 0:
         if ( is_hvm_domain(d) && (p->x86_vendor != old_vendor) )
         {
             struct vcpu *v;
@@ -167,9 +163,7 @@ static int update_domain_cpuid_info(struct domain *d,
             for_each_vcpu( d, v )
                 hvm_update_guest_vendor(v);
         }
-
         break;
-    }
 
     case 1:
         if ( is_pv_domain(d) && ((levelling_caps & LCAP_1cd) == LCAP_1cd) )
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index e5140ca..299a026 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -81,6 +81,7 @@ struct cpuid_policy
      *   - All of the feat and xstate unions
      *   - max_{,sub}leaf
      *   - All FEATURESET_* words
+     *   - Low short vendor infomation
      *
      * Per-domain objects:
      *
@@ -88,6 +89,7 @@ struct cpuid_policy
      *   - All of the feat and xstate unions
      *   - max_{,sub}leaf
      *   - All FEATURESET_* words
+     *   - Low short vendor infomation
      *
      * Everything else should be considered inaccurate, and not necesserily 0.
      */
@@ -101,7 +103,7 @@ struct cpuid_policy
         struct cpuid_leaf raw[CPUID_GUEST_NR_BASIC];
         struct {
             /* Leaf 0x0 - Max and vendor. */
-            uint32_t max_leaf, /* b */:32, /* c */:32, /* d */:32;
+            uint32_t max_leaf, vendor_ebx, vendor_ecx, vendor_edx;
 
             /* Leaf 0x1 - Family/model/stepping and features. */
             uint32_t raw_fms, /* b */:32;
-- 
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®.