This enables very aggressive DCE passes on single-vendor builds in later patches, as it will allow most vendor checks to become statically chosen branches. A lot of statics go away and a lot more inlining is allowed.
In order to allow x86_vendor_is() to fold into constants, expand Kconfig to have the full set of vendors. Adds Hygon, Centaur, Shanghai and the default path. Have Hygon depend on AMD, and Centaur+Shanghai depend on Intel. Not a functional change. Signed-off-by: Alejandro Vallejo <[email protected]> --- xen/arch/x86/Kconfig.cpu | 45 ++++++++++++++++++++++++++++++++ xen/arch/x86/cpu/common.c | 17 +++++++----- xen/arch/x86/include/asm/cpuid.h | 7 +++++ 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/Kconfig.cpu b/xen/arch/x86/Kconfig.cpu index 5fb18db1aa..aaf70fb37b 100644 --- a/xen/arch/x86/Kconfig.cpu +++ b/xen/arch/x86/Kconfig.cpu @@ -19,4 +19,49 @@ config INTEL May be turned off in builds targetting other vendors. Otherwise, must be enabled for Xen to work suitably on Intel platforms. +config HYGON + bool "Support Hygon CPUs" + depends on AMD + default y + help + Detection, tunings and quirks for Hygon platforms. + + May be turned off in builds targetting other vendors. Otherwise, + must be enabled for Xen to work suitably on Hygon platforms. + + +config CENTAUR + bool "Support Centaur CPUs" + depends on INTEL + default y + help + Detection, tunings and quirks for Centaur platforms. + + May be turned off in builds targetting other vendors. Otherwise, + must be enabled for Xen to work suitably on Centaur platforms. + +config SHANGHAI + bool "Support Shanghai CPUs" + depends on INTEL + default y + help + Detection, tunings and quirks for Shanghai platforms. + + May be turned off in builds targetting other vendors. Otherwise, + must be enabled for Xen to work suitably on Shanghai platforms. + +config UNKNOWN_CPU + bool "Support unknown CPUs" + default y + help + This option prevents a panic on boot when the host CPU vendor isn't + supported by going into a legacy compatibility mode and not applying + any relevant tunings or quirks. + + Not selecting this options while selecting multiple vendors doesn't have + any major effect on code size, but while selecting a single vendor + it produces a smaller build especially optimised for size. + + If unsure, say Y. + endmenu diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 37820a3a08..393c30227f 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -118,7 +118,7 @@ static void cf_check default_init(struct cpuinfo_x86 * c) __clear_bit(X86_FEATURE_SEP, c->x86_capability); } -static const struct cpu_dev __initconst_cf_clobber __used default_cpu = { +static const struct cpu_dev __initconst_cf_clobber default_cpu = { .c_init = default_init, }; static struct cpu_dev __ro_after_init actual_cpu; @@ -340,7 +340,8 @@ void __init early_cpu_init(bool verbose) *(u32 *)&c->x86_vendor_id[8] = ecx; *(u32 *)&c->x86_vendor_id[4] = edx; - c->x86_vendor = x86_cpuid_lookup_vendor(ebx, ecx, edx); + c->x86_vendor = x86_cpuid_lookup_vendor(ebx, ecx, edx) & + X86_ENABLED_VENDORS; switch (c->x86_vendor) { case X86_VENDOR_INTEL: intel_unlock_cpuid_leaves(c); actual_cpu = intel_cpu_dev; break; @@ -349,12 +350,14 @@ void __init early_cpu_init(bool verbose) case X86_VENDOR_SHANGHAI: actual_cpu = shanghai_cpu_dev; break; case X86_VENDOR_HYGON: actual_cpu = hygon_cpu_dev; break; default: + if (verbose || !IS_ENABLED(CONFIG_UNKNOWN_CPU)) + printk(XENLOG_ERR + "Unrecognised or unsupported CPU vendor '%.12s'\n", + c->x86_vendor_id); + if (!IS_ENABLED(CONFIG_UNKNOWN_CPU)) + panic("Cannot run in unknown/compiled-out CPU vendor.\n"); + actual_cpu = default_cpu; - if (!verbose) - break; - printk(XENLOG_ERR - "Unrecognised or unsupported CPU vendor '%.12s'\n", - c->x86_vendor_id); } cpuid(0x00000001, &eax, &ebx, &ecx, &edx); diff --git a/xen/arch/x86/include/asm/cpuid.h b/xen/arch/x86/include/asm/cpuid.h index f1b9e37a42..bf1c635cdd 100644 --- a/xen/arch/x86/include/asm/cpuid.h +++ b/xen/arch/x86/include/asm/cpuid.h @@ -49,6 +49,13 @@ struct cpuid_leaf; void guest_cpuid(const struct vcpu *v, uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res); +#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)) + #endif /* !__X86_CPUID_H__ */ /* -- 2.43.0
