Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP4
xen.23267
61f2d886-x86-CPUID-disentangle-new-leaves-logic...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 61f2d886-x86-CPUID-disentangle-new-leaves-logic.patch of Package xen.23267
# Commit e3662437eb43cc8002bd39be077ef68b131649c5 # Date 2022-01-27 17:38:15 +0000 # Author Andrew Cooper <andrew.cooper3@citrix.com> # Committer Andrew Cooper <andrew.cooper3@citrix.com> x86/cpuid: Disentangle logic for new feature leaves Adding a new feature leaf is a reasonable amount of boilerplate and for the patch to build, at least one feature from the new leaf needs defining. This typically causes two non-trivial changes to be merged together. First, have gen-cpuid.py write out some extra placeholder defines: #define CPUID_BITFIELD_11 bool :1, :1, lfence_dispatch:1, ... #define CPUID_BITFIELD_12 uint32_t :32 /* placeholder */ #define CPUID_BITFIELD_13 uint32_t :32 /* placeholder */ #define CPUID_BITFIELD_14 uint32_t :32 /* placeholder */ #define CPUID_BITFIELD_15 uint32_t :32 /* placeholder */ This allows DECL_BITFIELD() to be added to struct cpuid_policy without requiring a XEN_CPUFEATURE() declared for the leaf. The choice of 4 is arbitrary, and allows us to add more than one leaf at a time if necessary. Second, rework generic_identify() to not use specific feature names. The choice of deriving the index from a feature was to avoid mismatches, but its correctness depends on bugs like c/s 249e0f1d8f20 ("x86/cpuid: Fix TSXLDTRK definition") not happening. Switch to using FEATURESET_* just like the policy/featureset helpers. This breaks the cognitive complexity of needing to know which leaf a specifically named feature should reside in, and is shorter to write. It is also far easier to identify as correct at a glance, given the correlation with the CPUID leaf being read. In addition, tidy up some other bits of generic_identify() * Drop leading zeros from leaf numbers. * Don't use a locked update for X86_FEATURE_APERFMPERF. * Rework extended_cpuid_level calculation to avoid setting it twice. * Use "leaf >= $N" consistently so $N matches with the CPUID input. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -366,7 +366,7 @@ static void generic_identify(struct cpui u32 eax, ebx, ecx, edx, tmp; /* Get vendor name */ - cpuid(0x00000000, &c->cpuid_level, &ebx, &ecx, &edx); + cpuid(0, &c->cpuid_level, &ebx, &ecx, &edx); *(u32 *)&c->x86_vendor_id[0] = ebx; *(u32 *)&c->x86_vendor_id[8] = ecx; *(u32 *)&c->x86_vendor_id[4] = edx; @@ -381,7 +381,7 @@ static void generic_identify(struct cpui /* Note that the vendor-specific code below might override */ /* Model and family information. */ - cpuid(0x00000001, &eax, &ebx, &ecx, &edx); + cpuid(1, &eax, &ebx, &ecx, &edx); c->x86 = get_cpu_family(eax, &c->x86_model, &c->x86_mask); c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); c->phys_proc_id = c->apicid; @@ -391,53 +391,53 @@ static void generic_identify(struct cpui /* c_early_init() may have adjusted cpuid levels/features. Reread. */ c->cpuid_level = cpuid_eax(0); - cpuid(0x00000001, &eax, &ebx, &ecx, &edx); - c->x86_capability[cpufeat_word(X86_FEATURE_FPU)] = edx; - c->x86_capability[cpufeat_word(X86_FEATURE_SSE3)] = ecx; + cpuid(1, &eax, &ebx, + &c->x86_capability[FEATURESET_1c], + &c->x86_capability[FEATURESET_1d]); if ( cpu_has(c, X86_FEATURE_CLFLUSH) ) c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8; if ( (c->cpuid_level >= CPUID_PM_LEAF) && (cpuid_ecx(CPUID_PM_LEAF) & CPUID6_ECX_APERFMPERF_CAPABILITY) ) - set_bit(X86_FEATURE_APERFMPERF, c->x86_capability); + __set_bit(X86_FEATURE_APERFMPERF, c->x86_capability); + + eax = cpuid_eax(0x80000000); + if ((eax >> 16) == 0x8000) + c->extended_cpuid_level = eax; /* AMD-defined flags: level 0x80000001 */ - c->extended_cpuid_level = cpuid_eax(0x80000000); - if ((c->extended_cpuid_level >> 16) != 0x8000) - c->extended_cpuid_level = 0; - if (c->extended_cpuid_level > 0x80000000) + if (c->extended_cpuid_level >= 0x80000001) cpuid(0x80000001, &tmp, &tmp, - &c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)], - &c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]); + &c->x86_capability[FEATURESET_e1c], + &c->x86_capability[FEATURESET_e1d]); if (c->extended_cpuid_level >= 0x80000004) get_model_name(c); /* Default name */ if (c->extended_cpuid_level >= 0x80000007) - c->x86_capability[cpufeat_word(X86_FEATURE_ITSC)] - = cpuid_edx(0x80000007); + c->x86_capability[FEATURESET_e7d] = cpuid_edx(0x80000007); if (c->extended_cpuid_level >= 0x80000008) - c->x86_capability[cpufeat_word(X86_FEATURE_CLZERO)] - = cpuid_ebx(0x80000008); + c->x86_capability[FEATURESET_e8b] = cpuid_ebx(0x80000008); if (c->extended_cpuid_level >= 0x80000021) - c->x86_capability[cpufeat_word(X86_FEATURE_LFENCE_DISPATCH)] - = cpuid_eax(0x80000021); + c->x86_capability[FEATURESET_e21a] = cpuid_eax(0x80000021); /* Intel-defined flags: level 0x00000007 */ - if ( c->cpuid_level >= 0x00000007 ) { - cpuid_count(0x00000007, 0, &eax, - &c->x86_capability[cpufeat_word(X86_FEATURE_FSGSBASE)], - &c->x86_capability[cpufeat_word(X86_FEATURE_PKU)], - &c->x86_capability[cpufeat_word(X86_FEATURE_AVX512_4VNNIW)]); - if (eax > 0) - cpuid_count(0x00000007, 1, - &c->x86_capability[cpufeat_word(X86_FEATURE_AVX512_BF16)], + if (c->cpuid_level >= 7) { + uint32_t max_subleaf; + + cpuid_count(7, 0, &max_subleaf, + &c->x86_capability[FEATURESET_7b0], + &c->x86_capability[FEATURESET_7c0], + &c->x86_capability[FEATURESET_7d0]); + if (max_subleaf >= 1) + cpuid_count(7, 1, + &c->x86_capability[FEATURESET_7a1], &tmp, &tmp, &tmp); } if (c->cpuid_level >= 0xd) cpuid_count(0xd, 1, - &c->x86_capability[cpufeat_word(X86_FEATURE_XSAVEOPT)], + &c->x86_capability[FEATURESET_Da1], &tmp, &tmp, &tmp); } --- a/xen/tools/gen-cpuid.py +++ b/xen/tools/gen-cpuid.py @@ -421,6 +421,8 @@ def write_results(state): """) + state.bitfields += ["uint32_t :32 /* placeholder */"] * 4 + for idx, text in enumerate(state.bitfields): state.output.write( "#define CPUID_BITFIELD_%d \\\n %s\n\n"
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor