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

[Xen-devel] [PATCH v2 03/25] x86/cpuid: Move featuresets into struct cpuid_policy



Featuresets will eventually live only once in a struct cpuid_policy, but lots
of code currently uses the global featuresets as a linear bitmap.  Remove the
existing global *_featureset bitmaps, replacing them with *_policy objects
containing named featureset words and a fs[] linear bitmap.

Two new helpers are introduced to scatter/gather a linear featureset bitmap
to/from the fixed word locations in struct cpuid_policy.

The existing calculate_raw_policy() already obtains the scattered raw
featureset.  Gather the raw featureset into raw_policy.fs in
calculate_raw_policy() and drop calculate_raw_featureset() entirely.

Now that host_featureset can't be a straight define of
boot_cpu_data.x86_capability, introduce calculate_host_policy() to suitably
fill in host_policy from boot_cpu_data.x86_capability.  (Future changes will
have additional sanitization logic in this function.)

The PV and HVM policy objects and calculation functions have max introduced to
their names, as there will eventually be a distinction between max and default
policies for each domain type.  The existing logic works in terms of linear
bitmaps, so scatter the result back into the policy objects.

Leave some compatibility defines providing the old *_featureset API.  This
results in no observed change in the *_featureset values, which are still used
at the hypercall and guest_cpuid() interfaces.

Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v2:
 * Avoid double structs.
---
 xen/arch/x86/cpuid.c        | 64 +++++++++++++--------------------------
 xen/include/asm-x86/cpuid.h | 73 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 85 insertions(+), 52 deletions(-)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 1bfa7d7..b31eda7 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -14,13 +14,12 @@ static const uint32_t __initconst hvm_shadow_featuremask[] 
= INIT_HVM_SHADOW_FEA
 static const uint32_t __initconst hvm_hap_featuremask[] = 
INIT_HVM_HAP_FEATURES;
 static const uint32_t __initconst deep_features[] = INIT_DEEP_FEATURES;
 
-uint32_t __read_mostly raw_featureset[FSCAPINTS];
-uint32_t __read_mostly pv_featureset[FSCAPINTS];
-uint32_t __read_mostly hvm_featureset[FSCAPINTS];
-
 #define EMPTY_LEAF ((struct cpuid_leaf){})
 
-static struct cpuid_policy __read_mostly raw_policy;
+struct cpuid_policy __read_mostly raw_policy,
+    __read_mostly host_policy,
+    __read_mostly pv_max_policy,
+    __read_mostly hvm_max_policy;
 
 static void cpuid_leaf(uint32_t leaf, struct cpuid_leaf *data)
 {
@@ -130,47 +129,22 @@ static void __init calculate_raw_policy(void)
     for ( i = 1; i < min(ARRAY_SIZE(p->extd.raw),
                          p->extd.max_leaf + 1 - 0x80000000ul); ++i )
         cpuid_leaf(0x80000000 + i, &p->extd.raw[i]);
+
+    cpuid_policy_to_featureset(p, p->fs);
 }
 
-static void __init calculate_raw_featureset(void)
+static void __init calculate_host_policy(void)
 {
-    unsigned int max, tmp;
-
-    max = cpuid_eax(0);
-
-    if ( max >= 1 )
-        cpuid(0x1, &tmp, &tmp,
-              &raw_featureset[FEATURESET_1c],
-              &raw_featureset[FEATURESET_1d]);
-    if ( max >= 7 )
-        cpuid_count(0x7, 0, &tmp,
-                    &raw_featureset[FEATURESET_7b0],
-                    &raw_featureset[FEATURESET_7c0],
-                    &raw_featureset[FEATURESET_7d0]);
-    if ( max >= 0xd )
-        cpuid_count(0xd, 1,
-                    &raw_featureset[FEATURESET_Da1],
-                    &tmp, &tmp, &tmp);
-
-    max = cpuid_eax(0x80000000);
-    if ( (max >> 16) != 0x8000 )
-        return;
+    struct cpuid_policy *p = &host_policy;
 
-    if ( max >= 0x80000001 )
-        cpuid(0x80000001, &tmp, &tmp,
-              &raw_featureset[FEATURESET_e1c],
-              &raw_featureset[FEATURESET_e1d]);
-    if ( max >= 0x80000007 )
-        cpuid(0x80000007, &tmp, &tmp, &tmp,
-              &raw_featureset[FEATURESET_e7d]);
-    if ( max >= 0x80000008 )
-        cpuid(0x80000008, &tmp,
-              &raw_featureset[FEATURESET_e8b],
-              &tmp, &tmp);
+    memcpy(p->fs, boot_cpu_data.x86_capability, sizeof(p->fs));
+
+    cpuid_featureset_to_policy(host_featureset, p);
 }
 
-static void __init calculate_pv_featureset(void)
+static void __init calculate_pv_max_policy(void)
 {
+    struct cpuid_policy *p = &pv_max_policy;
     unsigned int i;
 
     for ( i = 0; i < FSCAPINTS; ++i )
@@ -188,10 +162,12 @@ static void __init calculate_pv_featureset(void)
     __set_bit(X86_FEATURE_CMP_LEGACY, pv_featureset);
 
     sanitise_featureset(pv_featureset);
+    cpuid_featureset_to_policy(pv_featureset, p);
 }
 
-static void __init calculate_hvm_featureset(void)
+static void __init calculate_hvm_max_policy(void)
 {
+    struct cpuid_policy *p = &hvm_max_policy;
     unsigned int i;
     const uint32_t *hvm_featuremask;
 
@@ -244,15 +220,15 @@ static void __init calculate_hvm_featureset(void)
     }
 
     sanitise_featureset(hvm_featureset);
+    cpuid_featureset_to_policy(hvm_featureset, p);
 }
 
 void __init init_guest_cpuid(void)
 {
     calculate_raw_policy();
-
-    calculate_raw_featureset();
-    calculate_pv_featureset();
-    calculate_hvm_featureset();
+    calculate_host_policy();
+    calculate_pv_max_policy();
+    calculate_hvm_max_policy();
 }
 
 const uint32_t * __init lookup_deep_deps(uint32_t feature)
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index 6176da7..0d0ac52 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -24,11 +24,6 @@
 extern const uint32_t known_features[FSCAPINTS];
 extern const uint32_t special_features[FSCAPINTS];
 
-extern uint32_t raw_featureset[FSCAPINTS];
-#define host_featureset boot_cpu_data.x86_capability
-extern uint32_t pv_featureset[FSCAPINTS];
-extern uint32_t hvm_featureset[FSCAPINTS];
-
 void init_guest_cpuid(void);
 
 const uint32_t *lookup_deep_deps(uint32_t feature);
@@ -87,7 +82,7 @@ struct cpuid_policy
      *   - {xcr0,xss}_{high,low}
      *
      * - Guest accurate:
-     *   - Nothing
+     *   - All FEATURESET_* words
      *
      * Everything else should be considered inaccurate, and not necesserily 0.
      */
@@ -98,6 +93,9 @@ struct cpuid_policy
         struct {
             /* Leaf 0x0 - Max and vendor. */
             uint32_t max_leaf, /* b */:32, /* c */:32, /* d */:32;
+
+            /* Leaf 0x1 - Family/model/stepping and features. */
+            uint32_t /* a */:32, /* b */:32, _1c, _1d;
         };
     } basic;
 
@@ -106,7 +104,7 @@ struct cpuid_policy
         struct cpuid_leaf raw[CPUID_GUEST_NR_FEAT];
         struct {
             /* Subleaf 0. */
-            uint32_t max_subleaf, /* b */:32, /* c */:32, /* d */:32;
+            uint32_t max_subleaf, _7b0, _7c0, _7d0;
         };
     } feat;
 
@@ -118,7 +116,7 @@ struct cpuid_policy
             uint32_t xcr0_low, /* b */:32, /* c */:32, xcr0_high;
 
             /* Subleaf 1. */
-            uint32_t /* a */:32, /* b */:32, xss_low, xss_high;
+            uint32_t Da1, /* b */:32, xss_low, xss_high;
         };
     } xstate;
 
@@ -128,10 +126,69 @@ struct cpuid_policy
         struct {
             /* Leaf 0x80000000 - Max and vendor. */
             uint32_t max_leaf, /* b */:32, /* c */:32, /* d */:32;
+
+            /* Leaf 0x80000001 - Family/model/stepping and features. */
+            uint32_t /* a */:32, /* b */:32, e1c, e1d;
+
+            uint64_t :64, :64; /* Brand string. */
+            uint64_t :64, :64; /* Brand string. */
+            uint64_t :64, :64; /* Brand string. */
+            uint64_t :64, :64; /* L1 cache/TLB. */
+            uint64_t :64, :64; /* L2/3 cache/TLB. */
+
+            /* Leaf 0x80000007 - Advanced Power Management. */
+            uint32_t /* a */:32, /* b */:32, /* c */:32, e7d;
+
+            /* Leaf 0x80000008 - Misc addr/feature info. */
+            uint32_t /* a */:32, e8b, /* c */:32, /* d */:32;
         };
     } extd;
+
+    /* Temporary featureset bitmap. */
+    uint32_t fs[FSCAPINTS];
 };
 
+/* Fill in a featureset bitmap from a CPUID policy. */
+static inline void cpuid_policy_to_featureset(
+    const struct cpuid_policy *p, uint32_t fs[FSCAPINTS])
+{
+    fs[FEATURESET_1d]  = p->basic._1d;
+    fs[FEATURESET_1c]  = p->basic._1c;
+    fs[FEATURESET_e1d] = p->extd.e1d;
+    fs[FEATURESET_e1c] = p->extd.e1c;
+    fs[FEATURESET_Da1] = p->xstate.Da1;
+    fs[FEATURESET_7b0] = p->feat._7b0;
+    fs[FEATURESET_7c0] = p->feat._7c0;
+    fs[FEATURESET_e7d] = p->extd.e7d;
+    fs[FEATURESET_e8b] = p->extd.e8b;
+    fs[FEATURESET_7d0] = p->feat._7d0;
+}
+
+/* Fill in a CPUID policy from a featureset bitmap. */
+static inline void cpuid_featureset_to_policy(
+    const uint32_t fs[FSCAPINTS], struct cpuid_policy *p)
+{
+    p->basic._1d  = fs[FEATURESET_1d];
+    p->basic._1c  = fs[FEATURESET_1c];
+    p->extd.e1d   = fs[FEATURESET_e1d];
+    p->extd.e1c   = fs[FEATURESET_e1c];
+    p->xstate.Da1 = fs[FEATURESET_Da1];
+    p->feat._7b0  = fs[FEATURESET_7b0];
+    p->feat._7c0  = fs[FEATURESET_7c0];
+    p->extd.e7d   = fs[FEATURESET_e7d];
+    p->extd.e8b   = fs[FEATURESET_e8b];
+    p->feat._7d0  = fs[FEATURESET_7d0];
+}
+
+extern struct cpuid_policy raw_policy, host_policy, pv_max_policy,
+    hvm_max_policy;
+
+/* Temporary compatibility defines. */
+#define raw_featureset raw_policy.fs
+#define host_featureset host_policy.fs
+#define pv_featureset pv_max_policy.fs
+#define hvm_featureset hvm_max_policy.fs
+
 void guest_cpuid(const struct vcpu *v, uint32_t leaf,
                  uint32_t subleaf, struct cpuid_leaf *res);
 
-- 
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®.