... which is in practice much earlier on boot. Currently, beyond basic vendor family and model information, the Intel hook needs the SELF_SNOOP CPUID bit which is collected by early_cpu_init() already. The AMD hook needs CPUID_USER_DIS, so the collection of leaf e21a needs to move too. (identify_cpu() has a second collection of this leaf, which remains.)
In order to facilitate this, have early_cpu_init() calculate c->extended_cpuid_level in the usual way. No practical change. Signed-off-by: Andrew Cooper <[email protected]> --- CC: Jan Beulich <[email protected]> CC: Roger Pau Monné <[email protected]> CC: Julian Vetter <[email protected]> CC: Teddy Astie <[email protected]> --- xen/arch/x86/cpu/common.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 39e64f3a5f88..d70f9cf87dc8 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -413,8 +413,12 @@ void __init early_cpu_init(bool verbose) } eax = cpuid_eax(0x80000000); - if ((eax >> 16) == 0x8000 && eax >= 0x80000008) { - ebx = eax >= 0x8000001f ? cpuid_ebx(0x8000001f) : 0; + if ((eax >> 16) == 0x8000) + c->extended_cpuid_level = eax; + + if (c->extended_cpuid_level >= 0x80000008) { + ebx = c->extended_cpuid_level >= 0x8000001f + ? cpuid_ebx(0x8000001f) : 0; eax = cpuid_eax(0x80000008); paddr_bits = eax & 0xff; @@ -433,6 +437,19 @@ void __init early_cpu_init(bool verbose) paddr_bits -= (ebx >> 6) & 0x3f; } + if (c->extended_cpuid_level >= 0x80000021) + c->x86_capability[FEATURESET_e21a] = cpuid_eax(0x80000021); + + /* + * Abuse 'verbose' to signal the first pass thought this function. + * + * Besides basic vendor, family and model information, the hooks need + * certain words of x86_capability[] already scanned, as they may take + * action to cause features to reappear. + */ + if (verbose && actual_cpu.c_early_init) + actual_cpu.c_early_init(); + if (!(c->x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON))) park_offline_cpus = opt_mce; @@ -485,10 +502,6 @@ void identify_cpu(struct cpuinfo_x86 *c) c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8; c->phys_proc_id = c->apicid; - /* - * Early init of Self Snoop support requires 0x1.edx, while there also - * set 0x1.ecx as the value is in context. - */ c->x86_capability[FEATURESET_1c] = ecx; c->x86_capability[FEATURESET_1d] = edx; @@ -496,16 +509,6 @@ void identify_cpu(struct cpuinfo_x86 *c) if ((eax >> 16) == 0x8000) c->extended_cpuid_level = eax; - /* - * These AMD-defined flags are out of place, but we need - * them early for the CPUID faulting probe code - */ - if (c->extended_cpuid_level >= 0x80000021) - c->x86_capability[FEATURESET_e21a] = cpuid_eax(0x80000021); - - if (c == &boot_cpu_data && actual_cpu.c_early_init) - alternative_vcall(actual_cpu.c_early_init); - /* AMD-defined flags: level 0x80000001 */ if (c->extended_cpuid_level >= 0x80000001) cpuid(0x80000001, &tmp, &tmp, -- 2.39.5
