diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 209c5052556d..af49e24b46a4 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2398,6 +2398,21 @@ static void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid) if (smp_num_siblings == 1 || !(apicid & mask)) cpumask_set_cpu(cpu, &__cpu_primary_thread_mask); } + +/* + * Due to the utter mess of CPUID evaluation smp_num_siblings is not valid + * during early boot. Initialize the primary thread mask before SMP + * bringup. + */ +static int __init smp_init_primary_thread_mask(void) +{ + unsigned int cpu; + + for (cpu = 0; cpu < nr_logical_cpuids; cpu++) + cpu_mark_primary_thread(cpu, cpuid_to_apicid[cpu]); + return 0; +} +early_initcall(smp_init_primary_thread_mask); #else static inline void cpu_mark_primary_thread(unsigned int cpu, unsigned int apicid) { } #endif @@ -2544,7 +2559,8 @@ int generic_processor_info(int apicid, int version) set_cpu_present(cpu, true); num_processors++; - cpu_mark_primary_thread(cpu, apicid); + if (system_state != SYSTEM_BOOTING) + cpu_mark_primary_thread(cpu, apicid); return cpu; }