[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] x86/CPU: re-work populating of cpu_data[]
commit 7126b7f806d54c41cbb2b828fefd49fd1d0a8bb9 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Thu Jul 17 08:54:02 2025 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Jul 17 08:54:02 2025 +0200 x86/CPU: re-work populating of cpu_data[] Forever since its introduction x86_mc_get_cpu_info() has been checking a structure field against BAD_APICID which would never have been set to that particular value. Arrange for this to actually be true ahead of CPU detection having run, which then also includes pruning after CPU removal. For this, - introduce a new helper function splitting reset logic out of identify_cpu(), and going slightly farther than the original code to achieve consistent results, - introduce a new helper macro for both initializing and resetting various fields. For boot_cpu_data this in particular means that cpuid_level will no longer be set to the bogus value of -1. Even before removal of 32-bit support we already assumed basic CPUID leaves to be available. Furthermore make sure initialize_cpu_data() doesn't populate fields with BSP's values which clearly aren't going to be applicable to APs. Fixes: e16fc5ba591c ("x86: mce: Provide extended physical CPU info") Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/cpu/common.c | 27 +++++++++++++++++---------- xen/arch/x86/include/asm/cpufeature.h | 18 ++++++++++++++++++ xen/arch/x86/setup.c | 2 +- xen/arch/x86/smpboot.c | 14 +++++++++----- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c index 77364fd728..08261edf17 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -415,6 +415,22 @@ void __init early_cpu_init(bool verbose) initialize_cpu_data(0); } +void reset_cpuinfo(struct cpuinfo_x86 *c, bool keep_basic) +{ + if ( !keep_basic ) + { + c->x86_vendor = 0; + c->x86 = 0; + c->x86_model = 0; + c->x86_mask = 0; + memset(&c->x86_capability, 0, sizeof(c->x86_capability)); + memset(&c->x86_vendor_id, 0, sizeof(c->x86_vendor_id)); + memset(&c->x86_model_id, 0, sizeof(c->x86_model_id)); + } + + CPU_DATA_INIT((*c)); +} + static void generic_identify(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx, tmp; @@ -522,16 +538,7 @@ void identify_cpu(struct cpuinfo_x86 *c) { int i; - c->x86_cache_size = -1; - c->x86_model = c->x86_mask = 0; /* So far unknown... */ - c->x86_model_id[0] = '\0'; /* Unset */ - c->x86_max_cores = 1; - c->x86_num_siblings = 1; - c->x86_clflush_size = 0; - c->cpu_core_id = XEN_INVALID_CORE_ID; - c->compute_unit_id = INVALID_CUID; - memset(&c->x86_capability, 0, sizeof c->x86_capability); - + reset_cpuinfo(c, false); generic_identify(c); #ifdef NOISY_CAPS diff --git a/xen/arch/x86/include/asm/cpufeature.h b/xen/arch/x86/include/asm/cpufeature.h index 3c2ac964e4..56d6ed1a87 100644 --- a/xen/arch/x86/include/asm/cpufeature.h +++ b/xen/arch/x86/include/asm/cpufeature.h @@ -41,6 +41,24 @@ struct cpuinfo_x86 { unsigned short x86_clflush_size; } __cacheline_aligned; +#define CPU_DATA_INIT(what...) \ + what.cpuid_level = 1, \ + what.extended_cpuid_level = 0, \ + what.x86_cache_size = -1, \ + what.x86_max_cores = 1, \ + what.x86_num_siblings = 1, \ + what.apicid = BAD_APICID, \ + what.phys_proc_id = XEN_INVALID_SOCKET_ID, \ + what.cpu_core_id = XEN_INVALID_CORE_ID, \ + what.compute_unit_id = INVALID_CUID + +/* + * @keep_basic set to true retains data firmly assumed to be symmetric + * across all CPUs. With it set to false only CPU_DATA_INIT() will be + * invoked on the passed structure. + */ +void reset_cpuinfo(struct cpuinfo_x86 *c, bool keep_basic); + extern struct cpuinfo_x86 boot_cpu_data; static inline bool cpu_has(const struct cpuinfo_x86 *info, unsigned int feat) diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 24e4f5ac7f..c6890669b9 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -178,7 +178,7 @@ void *stack_start = cpu0_stack + STACK_SIZE - sizeof(struct cpu_info); /* Used by the boot asm and EFI to stash the multiboot_info paddr. */ unsigned int __initdata multiboot_ptr; -struct cpuinfo_x86 __read_mostly boot_cpu_data = { 0, 0, 0, 0, -1 }; +struct cpuinfo_x86 __read_mostly boot_cpu_data = { CPU_DATA_INIT() }; unsigned long __read_mostly mmu_cr4_features = XEN_MINIMAL_CR4; diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index a90caf45a5..25bdd98fcf 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -69,7 +69,8 @@ unsigned int __read_mostly nr_sockets; cpumask_t **__read_mostly socket_cpumask; static cpumask_t *secondary_socket_cpumask; -struct cpuinfo_x86 cpu_data[NR_CPUS]; +struct cpuinfo_x86 __read_mostly cpu_data[NR_CPUS] = + { [0 ... NR_CPUS - 1] = { CPU_DATA_INIT() } }; u32 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; @@ -89,7 +90,12 @@ void *stack_base[NR_CPUS]; void initialize_cpu_data(unsigned int cpu) { - cpu_data[cpu] = boot_cpu_data; + struct cpuinfo_x86 c = boot_cpu_data; + + /* Must not partially clear the BSP's collected data. */ + if ( cpu || system_state > SYS_STATE_smp_boot ) + reset_cpuinfo(&c, true); + cpu_data[cpu] = c; } static bool smp_store_cpu_info(unsigned int id) @@ -968,9 +974,7 @@ static void cpu_smpboot_free(unsigned int cpu, bool remove) if ( remove ) { - c[cpu].phys_proc_id = XEN_INVALID_SOCKET_ID; - c[cpu].cpu_core_id = XEN_INVALID_CORE_ID; - c[cpu].compute_unit_id = INVALID_CUID; + reset_cpuinfo(&c[cpu], false); FREE_CPUMASK_VAR(per_cpu(cpu_sibling_mask, cpu)); FREE_CPUMASK_VAR(per_cpu(cpu_core_mask, cpu)); -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |