Bill XIE has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/69215 )
Change subject: cpu/x86/mp_init.c: Fix the logic to add AP cpus ......................................................................
cpu/x86/mp_init.c: Fix the logic to add AP cpus
https://review.coreboot.org/c/coreboot/+/64340 assumes (g_)cpu_bus->children->sibling represents the first AP cpu, but this is not true when device tree (like mb/asus/p8x7x-series/devicetree.cb) contains additional static lapic nodes. In such case, Linux kernel can find one cpu unable to wake up, and an additional working cpu without corresponding ACPI firmware node:
smpboot: Allowing 5 CPUs, 0 hotplug CPUs smpboot: CPU0: Intel(R) Xeon(R) CPU E3-1225 V2 @ 3.20GHz (family: 0x6, model: 0x3a, stepping: 0x9) smpboot: do_boot_cpu failed(-1) to wakeup CPU#2
Now, in the end of init_bsp(), the last apic node is held on g_last_apic, and all node representing an AP cpu should be inserted and set up after it. The consistency lost with CB:64340 should be restored now.
Signed-off-by: Bill XIE persmule@hardenedlinux.org Change-Id: I1075bc52091e619ef79cbeab0a0f6b57cff1d708 --- M src/cpu/x86/mp_init.c 1 file changed, 38 insertions(+), 4 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/15/69215/1
diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index febc30b..1aed394 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -172,7 +172,7 @@ stop_this_cpu(); }
-static struct bus *g_cpu_bus; +static struct device *g_last_apic;
/* By the time APs call ap_init() caching has been setup, and microcode has * been loaded. */ @@ -184,7 +184,7 @@ enable_lapic(); setup_lapic_interrupts();
- struct device *dev = g_cpu_bus->children; + struct device *dev = g_last_apic; for (unsigned int i = info->index; i > 0; i--) dev = dev->sibling;
@@ -534,6 +534,7 @@ { struct device_path cpu_path; struct cpu_info *info; + struct device *child;
/* Print processor name */ fill_processor_name(processor_name); @@ -559,6 +560,14 @@
/* Track BSP in cpu_map structures. */ cpu_add_map_entry(info->index); + + /* Find the last apic node, which may not be identical to + * cpu_bus->children. + */ + for (child = info->cpu; child && child->sibling; /* */) + child = child->sibling; + + g_last_apic = child; return CB_SUCCESS; }
@@ -584,8 +593,6 @@ int num_cpus; atomic_t *ap_count;
- g_cpu_bus = cpu_bus; - if (init_bsp(cpu_bus) != CB_SUCCESS) { printk(BIOS_CRIT, "Setting up BSP failed\n"); return CB_ERR;