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

[PATCH 03/12] x86: Add cpu_vendor() as a wrapper for the host's CPU vendor


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Alejandro Vallejo <alejandro.garciavallejo@xxxxxxx>
  • Date: Fri, 6 Feb 2026 17:15:25 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3XqRfkRYraueuo3h0D16mjrku9u0GK6eRvjfilF9NFM=; b=ELk9Hu02OLTU6CxxZ+0kfq8vUHhPGEJHUd4p4UyI5oZ6k0+L/F8TtgDQy7UuNvZ70KrlE/41OExBqpA3D+bg9FNeeZu1AsjOFpRXBsgGT5fJTHPLlYv9Lodtu32d4LHqaujLpRaCcX6Q6hA/jUv+lZuLIokkupau7z9WjcSSQY66gE3pR+jqI3/I+3NkjYEM+aPlTY4ybvKbz0LzmqkLUAFHrYkPPAh1wYEglh7D1BHg1SG6eMeCIS2zf9mRiv9Q2usWiK59SpYeuUVq60HEJwGYwNCYqTGd4UmCrzRG8c1f7cPXzK8hY4mC5tRMuAEL7LJXfFvlYYUpOMCysbxsPQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=aRxQ6yAe1818+J4I+sHXFyvZzfwUyY66oinUDS4T9DpKe2gkHtYXncbbaIuKX6F7kmbuyAtF4IdclZuUkwwJme36D0/KhM5FA6rWX5FQgDw7mpINWuK8NYAFmsI/3/P72gfDbXFgGJgzqoAEELduEyYbzG+XcYqOrbS3LwBylNNTdpvi1pfXFA+B5Vx0xM4R+qdNVuzVWVWqmtoSrromM+geD7oU2xKuoUzt+86SIk2C2kxCWJ+xfLGFMakaUgWD2Evn8DDtpQ4HzdlC19c2L+xmWxTxkxPPRa6a4Ne2zB8c4DkNeRl9ewnj86w8YRuUWsmSqWm3mWtMQm30E2Xaag==
  • Cc: Alejandro Vallejo <alejandro.garciavallejo@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Jason Andryuk <jason.andryuk@xxxxxxx>
  • Delivery-date: Fri, 06 Feb 2026 16:16:14 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Introduces various optimisations that rely on constant folding, Value
Range Propagation (VRP), and Dead Code Elimination (DCE) to aggressively
eliminate code surrounding the uses of the function.

  * For single-vendor+no-unknown-vendor builds returns a compile-time
    constant.
  * For all other cases it ANDs the result with the mask of compiled
    vendors, with the effect of performing DCE in switch cases, removing
    dead conditionals, etc.

It's difficult to reason about codegen in general in a project this big,
but in this case the ANDed constant combines with the values typically
checked against, folding into a comparison against zero. Thus, it's better
for codegen to AND its result with the desired compared-against vendor,
rather than using (in)equality operators. That way the comparison is
always against zero.

  "cpu_vendor() & (X86_VENDOR_AMD | X86_VENDOR_HYGON)"

turns into (cpu_vendor() & X86_VENDOR_AMD) in AMD-only builds (AND +
cmp with zero). Whereas this...

  "cpu_vendor() == X86_VENDOR_AMD"

forces cpu_vendor() to be ANDed and then compared to a non-zero value.

Later patches take the opportunity and make this refactor as cpu_vendor()
is introduced throughout the tree.

Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@xxxxxxx>
---
 xen/arch/x86/cpu/common.c             |  6 +++++-
 xen/arch/x86/guest/xen/xen.c          |  4 ++++
 xen/arch/x86/include/asm/cpufeature.h | 27 +++++++++++++++++++++++++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index ebe2baf8b9..6f4e723172 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -328,7 +328,11 @@ void __init early_cpu_init(bool verbose)
        *(u32 *)&c->x86_vendor_id[4] = edx;
 
        c->x86_vendor = x86_cpuid_lookup_vendor(ebx, ecx, edx);
-       switch (c->x86_vendor) {
+       if ( c->x86_vendor != cpu_vendor() )
+               panic("CPU vendor not compiled-in: %s",
+                     x86_cpuid_vendor_to_str(c->x86_vendor));
+
+       switch (cpu_vendor()) {
        case X86_VENDOR_INTEL:    intel_unlock_cpuid_leaves(c);
                                  actual_cpu = intel_cpu_dev;    break;
        case X86_VENDOR_AMD:      actual_cpu = amd_cpu_dev;      break;
diff --git a/xen/arch/x86/guest/xen/xen.c b/xen/arch/x86/guest/xen/xen.c
index 77a3a8742a..ec558bcbdb 100644
--- a/xen/arch/x86/guest/xen/xen.c
+++ b/xen/arch/x86/guest/xen/xen.c
@@ -57,6 +57,10 @@ void asmlinkage __init early_hypercall_setup(void)
         cpuid(0, &eax, &ebx, &ecx, &edx);
 
         boot_cpu_data.x86_vendor = x86_cpuid_lookup_vendor(ebx, ecx, edx);
+
+        if ( cpu_vendor() != boot_cpu_data.x86_vendor )
+            panic("CPU vendor not compiled-in: %s",
+                  x86_cpuid_vendor_to_str(boot_cpu_data.x86_vendor));
     }
 
     switch ( boot_cpu_data.x86_vendor )
diff --git a/xen/arch/x86/include/asm/cpufeature.h 
b/xen/arch/x86/include/asm/cpufeature.h
index dcd223d84f..10309e40b6 100644
--- a/xen/arch/x86/include/asm/cpufeature.h
+++ b/xen/arch/x86/include/asm/cpufeature.h
@@ -14,6 +14,7 @@
 #include <asm/cpu-policy.h>
 #include <asm/cpuid.h>
 #include <xen/lib/x86/cpu-policy.h>
+#include <asm/x86-vendors.h>
 #else
 #include <asm/cpufeatureset.h>
 #endif
@@ -116,6 +117,32 @@ static inline bool boot_cpu_has(unsigned int feat)
 
 #define CPUID_PM_LEAF                                6
 
+#define X86_ENABLED_VENDORS \
+    ((IS_ENABLED(CONFIG_INTEL)    ? X86_VENDOR_INTEL    : 0) | \
+     (IS_ENABLED(CONFIG_AMD)      ? X86_VENDOR_AMD      : 0) | \
+     (IS_ENABLED(CONFIG_CENTAUR)  ? X86_VENDOR_CENTAUR  : 0) | \
+     (IS_ENABLED(CONFIG_SHANGHAI) ? X86_VENDOR_SHANGHAI : 0) | \
+     (IS_ENABLED(CONFIG_HYGON)    ? X86_VENDOR_HYGON    : 0))
+
+static always_inline uint8_t cpu_vendor(void)
+{
+    uint8_t vendor = boot_cpu_data.vendor;
+
+    /*
+     * const-ify the CPU vendor if we compiled for a single vendor and there's
+     * no boot path for an unknown vendor.
+     */
+    if ( !IS_ENABLED(CONFIG_UNKNOWN_CPU_VENDOR) &&
+         (ISOLATE_LSB(X86_ENABLED_VENDORS) == X86_ENABLED_VENDORS) )
+        return X86_ENABLED_VENDORS;
+
+    /*
+     * This allows the compiler to know more in its VRP pass about the valid
+     * range of `vendor`. It enhances DCE by eliminating impossible vendors.
+     */
+    return vendor & X86_ENABLED_VENDORS;
+}
+
 /* CPUID level 0x00000001.edx */
 #define cpu_has_fpu             1
 #define cpu_has_de              1
-- 
2.43.0




 


Rackspace

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