libx86: Recalculate synthesised cpuid_policy fields when appropriate
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 10 Jul 2018 12:53:21 +0000 (13:53 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 27 Mar 2019 14:45:47 +0000 (14:45 +0000)
When filling a policy, either from CPUID or an incomming leaf stream,
recalculate the synthesised vendor value.  All callers are expected to want
this behaviour.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/cpuid.c
xen/include/xen/lib/x86/cpuid.h
xen/lib/x86/cpuid.c

index b5eb584a47570f97709bda50ff8b62dc712d4d50..cb170ac4d764f0d1b88b05b6cc9754efb8a9c06f 100644 (file)
@@ -272,7 +272,8 @@ static void __init calculate_raw_policy(void)
 
     x86_cpuid_policy_fill_native(p);
 
-    p->x86_vendor = boot_cpu_data.x86_vendor;
+    /* Nothing good will come from Xen and libx86 disagreeing on vendor. */
+    ASSERT(p->x86_vendor == boot_cpu_data.x86_vendor);
 }
 
 static void __init calculate_host_policy(void)
index f392c78358b880a4f1a8265094154f2f60b50d88..c7a3bffeda1a35282aed5edf17c2533d94a6e0ca 100644 (file)
@@ -297,8 +297,9 @@ const uint32_t *x86_cpuid_lookup_deep_deps(uint32_t feature);
 /**
  * Fill a CPUID policy using the native CPUID instruction.
  *
- * No sanitisation is performed.  Values may be influenced by a hypervisor or
- * from masking/faulting configuration.
+ * No sanitisation is performed, but synthesised values are calculated.
+ * Values may be influenced by a hypervisor or from masking/faulting
+ * configuration.
  */
 void x86_cpuid_policy_fill_native(struct cpuid_policy *p);
 
@@ -339,7 +340,8 @@ int x86_cpuid_copy_to_buffer(const struct cpuid_policy *policy,
  * incoming leaf is out of range of cpuid_policy, in which case the optional
  * err_* pointers are filled to aid diagnostics.
  *
- * No content validation of in-range leaves is performed.
+ * No content validation of in-range leaves is performed.  Synthesised data is
+ * recalculated.
  */
 int x86_cpuid_copy_from_buffer(struct cpuid_policy *policy,
                                const cpuid_leaf_buffer_t leaves,
index 104a8670649b0d2cac73b4c023980c1523b5bdda..311d19e471dd11fdb0607f9cdce87d3157430f8f 100644 (file)
@@ -34,6 +34,13 @@ unsigned int x86_cpuid_lookup_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx)
     return X86_VENDOR_UNKNOWN;
 }
 
+/* Recalculate the content in a CPUID policy which is derived from raw data. */
+static void recalculate_synth(struct cpuid_policy *p)
+{
+    p->x86_vendor = x86_cpuid_lookup_vendor(
+        p->basic.vendor_ebx, p->basic.vendor_ecx, p->basic.vendor_edx);
+}
+
 void x86_cpuid_policy_fill_native(struct cpuid_policy *p)
 {
     unsigned int i;
@@ -141,6 +148,8 @@ void x86_cpuid_policy_fill_native(struct cpuid_policy *p)
     for ( i = 1; i < min_t(unsigned int, ARRAY_SIZE(p->extd.raw),
                            p->extd.max_leaf + 1 - 0x80000000); ++i )
         cpuid_leaf(0x80000000 + i, &p->extd.raw[i]);
+
+    recalculate_synth(p);
 }
 
 const uint32_t *x86_cpuid_lookup_deep_deps(uint32_t feature)
@@ -363,6 +372,8 @@ int x86_cpuid_copy_from_buffer(struct cpuid_policy *p,
         }
     }
 
+    recalculate_synth(p);
+
     return 0;
 
  out_of_range: