The BSP starts APs with a broadcast INIT/STARTUP IPI, so every exposed AP
runs this code, including the ones the kernel rejected.  Rejected APIC
IDs are -1 in cpu_id_lut; test the lookup and park before using it to
index percpu_array or the per-CPU GDT.
---
 i386/i386/cpuboot.S | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/i386/i386/cpuboot.S b/i386/i386/cpuboot.S
index fd3d632..68c4b79 100644
--- a/i386/i386/cpuboot.S
+++ b/i386/i386/cpuboot.S
@@ -168,6 +168,12 @@ apboot32:
        andb    %cs:apic_id_mask, %bl
        movl    %cs:CX(cpu_id_lut, %ebx), %ebp
 
+       /* Park APs the kernel did not accept (cpu_id_lut == -1). */
+       testl   %ebp, %ebp
+       js      apboot_park
+       cmpl    $NCPUS, %ebp
+       jae     apboot_park
+
        /* Copy first gdt descriptor and gdt to cpu-th area */
        movl    $(GDT_DESCR_M32 + GDT_TABLE_M32), %ecx
        movl    $apboot_gdt_top, %esi
@@ -276,5 +282,12 @@ apboot_jmp_offset:
        .long RELOC(apboot32)
        .word BOOT_CS
 
+.align 16
+apboot_park:
+       cli
+apboot_park_loop:
+       hlt
+       jmp     apboot_park_loop
+
 apbootend:
 #endif

Reply via email to