]> git.karo-electronics.de Git - linux-beck.git/commitdiff
x86: fix CONFIG_NUMA and nosmp | maxcpus=0/1 crash
authorIngo Molnar <mingo@elte.hu>
Fri, 19 Oct 2007 18:35:02 +0000 (20:35 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Fri, 19 Oct 2007 18:35:02 +0000 (20:35 +0200)
x86 NUMA kernels crash in the scheduler setup code if "nosmp" or
"maxcpus=0" is passed on the boot command line:

| Brought up 1 CPUs
| BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
| printing eip: c011f0b5 *pde = 00000000
| Oops: 0000 [#1] SMP
|
| Pid: 1, comm: swapper Not tainted (2.6.23 #67)
| EIP: 0060:[<c011f0b5>] EFLAGS: 00010246 CPU: 0
| EIP is at sd_degenerate+0x35/0x40

the reason is sloppy spaghetti code in smpboot_32.c that resulted in a
missing map_cpu_to_logical_apicid() call - which also had the side-effect
of setting up the cpu_2_node[] entry for the lone CPU. That resulted in
node_to_cpumask(0) resulting in 00000000 - confusing the sched-domains
setup code.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
arch/x86/kernel/smpboot_32.c

index be3faac047190e2647d95baae8d0322dc1a922c4..65e5de7d64dbd2b77de1a0933060d33c670f35fc 100644 (file)
@@ -1008,6 +1008,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               map_cpu_to_logical_apicid();
                cpu_set(0, per_cpu(cpu_sibling_map, 0));
                cpu_set(0, per_cpu(cpu_core_map, 0));
                return;
@@ -1029,6 +1030,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                }
                smpboot_clear_io_apic_irqs();
                phys_cpu_present_map = physid_mask_of_physid(0);
+               map_cpu_to_logical_apicid();
                cpu_set(0, per_cpu(cpu_sibling_map, 0));
                cpu_set(0, per_cpu(cpu_core_map, 0));
                return;