From 53d7472637e44e7b6f73c1afce96e230a3e3e144 Mon Sep 17 00:00:00 2001 From: Travis Geiselbrecht Date: Mon, 17 May 2010 03:47:24 +0000 Subject: [PATCH] BOOT SMP: allow systems with a large number of cpus and/or sparse apic ids to actually boot The old mechanism to route an apic id back to a cpu id is faulty, built with the assumption that the bios will 'pack' the apic ids from 0-num_cpus. In systems that dont do that, the code would randomly corrupt the bootloader. Fatal in this case. This quick fix simply rejects all apic ids >= MAX_CPUS (8). No way it would have worked before if you had a box that started with >= 8 or anything, so it shouldn't regress any existing system. Better solution is to allow any apic id to exist (0-255). On this particular box the ids (from lunix dmesg): SRAT: PXM 0 -> APIC 0 -> Node 0 SRAT: PXM 1 -> APIC 16 -> Node 1 SRAT: PXM 0 -> APIC 2 -> Node 0 SRAT: PXM 0 -> APIC 4 -> Node 0 SRAT: PXM 0 -> APIC 6 -> Node 0 SRAT: PXM 1 -> APIC 18 -> Node 1 SRAT: PXM 1 -> APIC 20 -> Node 1 SRAT: PXM 1 -> APIC 22 -> Node 1 SRAT: PXM 0 -> APIC 1 -> Node 0 SRAT: PXM 0 -> APIC 3 -> Node 0 SRAT: PXM 0 -> APIC 5 -> Node 0 SRAT: PXM 0 -> APIC 7 -> Node 0 SRAT: PXM 1 -> APIC 17 -> Node 1 SRAT: PXM 1 -> APIC 19 -> Node 1 SRAT: PXM 1 -> APIC 21 -> Node 1 SRAT: PXM 1 -> APIC 23 -> Node 1 git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36836 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/boot/platform/bios_ia32/smp.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/system/boot/platform/bios_ia32/smp.cpp b/src/system/boot/platform/bios_ia32/smp.cpp index 779680e130..2714d5b3d6 100644 --- a/src/system/boot/platform/bios_ia32/smp.cpp +++ b/src/system/boot/platform/bios_ia32/smp.cpp @@ -165,6 +165,12 @@ smp_do_mp_config(mp_floating_struct *floatingStruct) continue; } + // skip if the apic id is too large + if (processor->apic_id >= MAX_BOOT_CPUS) { + TRACE(("smp: apic id too large (%d)\n", processor->apic_id)); + continue; + } + gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = processor->apic_id; gKernelArgs.arch_args.cpu_os_id[processor->apic_id] @@ -274,6 +280,12 @@ smp_do_acpi_config(void) break; } + // skip if the apic id is too large + if (localApic->apic_id >= MAX_BOOT_CPUS) { + TRACE(("smp: apic id too large (%d)\n", localApic->apic_id)); + break; + } + gKernelArgs.arch_args.cpu_apic_id[gKernelArgs.num_cpus] = localApic->apic_id; gKernelArgs.arch_args.cpu_os_id[localApic->apic_id]