x86/cpuid: Drop a guests cached x86 family and model information
authorAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 12 Jan 2017 11:45:10 +0000 (11:45 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 18 Jan 2017 12:45:52 +0000 (12:45 +0000)
The model information isn't used at all, and the family information is only
used once.

Make get_cpu_family() a static inline (as it is just basic calculation, and
the function call is probably more expensive than the function itself) and
rearange the logic to avoid calculating model entirely if the caller doesn't
want it.

Calculate a guests family only when necessary in hvm_select_ioreq_server().

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/cpu/common.c
xen/arch/x86/domain.c
xen/arch/x86/domctl.c
xen/arch/x86/hvm/ioreq.c
xen/include/asm-x86/cpuid.h
xen/include/asm-x86/domain.h
xen/include/asm-x86/processor.h

index 7d6d0249e5271c2a6ab002b68e92bfa97b0f9eb1..56a233127378b394559745ab5d4e6e164e08a53c 100644 (file)
@@ -186,25 +186,6 @@ int get_cpu_vendor(uint32_t b, uint32_t c, uint32_t d, enum get_cpu_vendor mode)
        return X86_VENDOR_UNKNOWN;
 }
 
-uint8_t get_cpu_family(uint32_t raw, uint8_t *model, uint8_t *stepping)
-{
-       uint8_t fam, mod;
-
-       fam = (raw >> 8) & 0xf;
-       if (fam == 0xf)
-               fam += (raw >> 20) & 0xff;
-
-       mod = (raw >> 4) & 0xf;
-       if (fam >= 0x6)
-               mod |= (raw >> 12) & 0xf0;
-
-       if (model)
-               *model = mod;
-       if (stepping)
-               *stepping = raw & 0xf;
-       return fam;
-}
-
 static inline u32 _phys_pkg_id(u32 cpuid_apic, int index_msb)
 {
        return cpuid_apic >> index_msb;
index 56669fccc7f0bf1670c882c653b9155c29d08336..354f3866a840a211372cdd0a7a5f3223c454b6f2 100644 (file)
@@ -609,8 +609,6 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
             goto fail;
 
         d->arch.x86_vendor = boot_cpu_data.x86_vendor;
-        d->arch.x86        = boot_cpu_data.x86;
-        d->arch.x86_model  = boot_cpu_data.x86_model;
 
         d->arch.ioport_caps = 
             rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex);
index 772c5d29701aa509c09223a414133425d833da93..0458d8f47804f164551bef0b0651a404961b04f7 100644 (file)
@@ -171,8 +171,6 @@ static int update_domain_cpuid_info(struct domain *d,
     }
 
     case 1:
-        d->arch.x86 = get_cpu_family(ctl->eax, &d->arch.x86_model, NULL);
-
         if ( is_pv_domain(d) && ((levelling_caps & LCAP_1cd) == LCAP_1cd) )
         {
             uint64_t mask = cpuidmask_defaults._1cd;
index 2830f6ccca5f5ba23546dc88daaf04711dee63da..8ad84654245a52f8c649f59342f90e1d2d7a4b74 100644 (file)
@@ -1125,7 +1125,7 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
          (p->addr & ~3) == 0xcfc &&
          CF8_ENABLED(cf8) )
     {
-        uint32_t sbdf;
+        uint32_t sbdf, x86_fam;
 
         /* PCI config data cycle */
 
@@ -1141,7 +1141,9 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
         /* AMD extended configuration space access? */
         if ( CF8_ADDR_HI(cf8) &&
              d->arch.x86_vendor == X86_VENDOR_AMD &&
-             d->arch.x86 >= 0x10 && d->arch.x86 <= 0x17 )
+             (x86_fam = get_cpu_family(
+                 d->arch.cpuid->basic.raw_fms, NULL, NULL)) > 0x10 &&
+             x86_fam <= 0x17 )
         {
             uint64_t msr_val;
 
index b359b38a2f2b5e94bc57917c3d858f14b4497b6e..c56190b762195731d15d1390d4e0c8c0ffcde6eb 100644 (file)
@@ -107,7 +107,7 @@ struct cpuid_policy
             uint32_t max_leaf, /* b */:32, /* c */:32, /* d */:32;
 
             /* Leaf 0x1 - Family/model/stepping and features. */
-            uint32_t /* a */:32, /* b */:32;
+            uint32_t raw_fms, /* b */:32;
             union {
                 uint32_t _1c;
                 struct { DECL_BITFIELD(1c); };
index eb6227d0ad2bba4d4d7df372936a63bd3f04c284..82296c8756c48ab59fcb094152f11fa5d2131287 100644 (file)
@@ -338,9 +338,7 @@ struct arch_domain
     bool_t auto_unmask;
 
     /* Values snooped from updates to cpuids[] (below). */
-    u8 x86;                  /* CPU family */
     u8 x86_vendor;           /* CPU vendor */
-    u8 x86_model;            /* CPU model */
 
     /*
      * The width of the FIP/FDP register in the FPU that needs to be
index b130f47103777309591e79279b70816e18baba40..3b859a59e19bd55e8af12e7a5c7f81af533751be 100644 (file)
@@ -625,7 +625,28 @@ enum get_cpu_vendor {
 };
 
 int get_cpu_vendor(uint32_t b, uint32_t c, uint32_t d, enum get_cpu_vendor mode);
-uint8_t get_cpu_family(uint32_t raw, uint8_t *model, uint8_t *stepping);
+
+static inline uint8_t get_cpu_family(uint32_t raw, uint8_t *model,
+                                     uint8_t *stepping)
+{
+    uint8_t fam = (raw >> 8) & 0xf;
+
+    if ( fam == 0xf )
+        fam += (raw >> 20) & 0xff;
+
+    if ( model )
+    {
+        uint8_t mod = (raw >> 4) & 0xf;
+
+        if ( fam >= 0x6 )
+            mod |= (raw >> 12) & 0xf0;
+
+        *model = mod;
+    }
+    if ( stepping )
+        *stepping = raw & 0xf;
+    return fam;
+}
 
 #endif /* !__ASSEMBLY__ */