This function is meant to replace all instances of the following patterns in CPU policies and boot_cpu_data:
- x->x86_vendor == X86_VENDOR_FOO - x->x86_vendor != X86_VENDOR_FOO - x->x86_vendor & (X86_VENDOR_FOO | X86_VENDOR_BAR) The secret sauce is that all branches inside the helper resolve at compile time, so for the all-vendors-compiled-in case the function resolves to equivalent code as that without the helper and you get progressively more aggressive DCE as you disable vendors. The function folds into a constant once you remove the fallback CPU vendor setting. While at this, move an include out of place so they sort alphabetically. Not a functional change. Signed-off-by: Alejandro Vallejo <[email protected]> --- xen/arch/x86/include/asm/cpuid.h | 49 +++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/include/asm/cpuid.h b/xen/arch/x86/include/asm/cpuid.h index bf1c635cdd..a4280d1b0d 100644 --- a/xen/arch/x86/include/asm/cpuid.h +++ b/xen/arch/x86/include/asm/cpuid.h @@ -2,10 +2,12 @@ #define __X86_CPUID_H__ #include <asm/cpufeatureset.h> +#include <asm/x86-vendors.h> -#include <xen/types.h> +#include <xen/compiler.h> #include <xen/kernel.h> #include <xen/percpu.h> +#include <xen/types.h> #include <public/sysctl.h> @@ -56,6 +58,51 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, (IS_ENABLED(CONFIG_SHANGHAI) ? X86_VENDOR_SHANGHAI : 0) | \ (IS_ENABLED(CONFIG_HYGON) ? X86_VENDOR_HYGON : 0)) +/* + * When compiling Xen for a single vendor with no fallback vendor there's no + * need no check the candidate. `vendor` is always a compile-time constant, + * which means this all can fold into a constant boolean. + * + * A runtime check at the time of CPUID probing guarantees we never run on + * wrong hardware and another check when loading CPU policies guarantees we + * never run policies for a vendor in another vendor's silicon. + * + * By the same token, the same folding can happen when no vendor is compiled + * in and the fallback path is present. + */ +static always_inline bool x86_vendor_is(uint8_t candidate, uint8_t vendor) +{ + uint8_t filtered_vendor = vendor & X86_ENABLED_VENDORS; + + if ( vendor == X86_VENDOR_UNKNOWN ) + { + if ( IS_ENABLED(CONFIG_UNKNOWN_CPU) ) + /* no-vendor optimisation */ + return X86_ENABLED_VENDORS ? vendor == candidate : true; + + /* unknown-vendor-elimination optimisation */ + return false; + } + + /* single-vendor optimisation */ + if ( !IS_ENABLED(CONFIG_UNKNOWN_CPU) && + (ISOLATE_LSB(X86_ENABLED_VENDORS) == X86_ENABLED_VENDORS) ) + return filtered_vendor == X86_ENABLED_VENDORS; + + /* compiled-out-vendor-elimination optimisation */ + if ( !filtered_vendor ) + return false; + + /* + * When checking against a single vendor, perform an equality check, as + * it yields (marginally) better codegen + */ + if ( ISOLATE_LSB(filtered_vendor) == filtered_vendor ) + return filtered_vendor == candidate ; + + return filtered_vendor & candidate; +} + #endif /* !__X86_CPUID_H__ */ /* -- 2.43.0
