From: Russell King Date: Thu, 16 Feb 2006 11:08:09 +0000 (+0000) Subject: [ARM] Fix SMP initialisation oops X-Git-Tag: v2.6.16-rc4~29^2~3 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bbb79403163e047c6e333ff169db34e3c969e65;p=linux-2.6 [ARM] Fix SMP initialisation oops A change to the SMP initialisation caused the following oops: CPU1: Booted secondary processor CPU1: D VIPT write-back cache CPU1: I cache: 32768 bytes, associativity 4, 32 byte lines, 256 sets CPU1: D cache: 32768 bytes, associativity 4, 32 byte lines, 256 sets <7>Calibrating delay loop... 83.14 BogoMIPS (lpj=415744) <1>Unable to handle kernel NULL pointer dereference at virtual address 0000001c ... PC is at enqueue_task+0x1c/0x64 LR is at activate_task+0xcc/0xe4 SMP initialisation now requires cpu_possible_map to be initialised in setup_arch(). Move this from smp_prepare_cpus() to smp_init_cpus() and call it from our setup_arch() if CONFIG_SMP is enabled. Signed-off-by: Russell King --- diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index c45d10d07b..68273b4dc8 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -771,6 +772,10 @@ void __init setup_arch(char **cmdline_p) paging_init(&meminfo, mdesc); request_standard_resources(&meminfo, mdesc); +#ifdef CONFIG_SMP + smp_init_cpus(); +#endif + cpu_init(); /* diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7338948bd7..02aa300c46 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -338,7 +338,6 @@ void __init smp_prepare_boot_cpu(void) per_cpu(cpu_data, cpu).idle = current; - cpu_set(cpu, cpu_possible_map); cpu_set(cpu, cpu_present_map); cpu_set(cpu, cpu_online_map); } diff --git a/arch/arm/mach-integrator/platsmp.c b/arch/arm/mach-integrator/platsmp.c index ea10bd8c97..1bc8534ef0 100644 --- a/arch/arm/mach-integrator/platsmp.c +++ b/arch/arm/mach-integrator/platsmp.c @@ -140,6 +140,18 @@ static void __init poke_milo(void) mb(); } +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +void __init smp_init_cpus(void) +{ + unsigned int i, ncores = get_core_count(); + + for (i = 0; i < ncores; i++) + cpu_set(i, cpu_possible_map); +} + void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int ncores = get_core_count(); @@ -176,14 +188,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) max_cpus = ncores; /* - * Initialise the possible/present maps. - * cpu_possible_map describes the set of CPUs which may be present - * cpu_present_map describes the set of CPUs populated + * Initialise the present map, which describes the set of CPUs + * actually populated at the present time. */ - for (i = 0; i < max_cpus; i++) { - cpu_set(i, cpu_possible_map); + for (i = 0; i < max_cpus; i++) cpu_set(i, cpu_present_map); - } /* * Do we need any more CPUs? If so, then let them know where diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index a8fbd76d8b..b8484e15da 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c @@ -143,6 +143,18 @@ static void __init poke_milo(void) mb(); } +/* + * Initialise the CPU possible map early - this describes the CPUs + * which may be present or become present in the system. + */ +void __init smp_init_cpus(void) +{ + unsigned int i, ncores = get_core_count(); + + for (i = 0; i < ncores; i++) + cpu_set(i, cpu_possible_map); +} + void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int ncores = get_core_count(); @@ -179,14 +191,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) local_timer_setup(cpu); /* - * Initialise the possible/present maps. - * cpu_possible_map describes the set of CPUs which may be present - * cpu_present_map describes the set of CPUs populated + * Initialise the present map, which describes the set of CPUs + * actually populated at the present time. */ - for (i = 0; i < max_cpus; i++) { - cpu_set(i, cpu_possible_map); + for (i = 0; i < max_cpus; i++) cpu_set(i, cpu_present_map); - } /* * Do we need any more CPUs? If so, then let them know where diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h index 5a72e50ca9..fe45f7f612 100644 --- a/include/asm-arm/smp.h +++ b/include/asm-arm/smp.h @@ -41,6 +41,11 @@ extern void show_ipi_list(struct seq_file *p); */ asmlinkage void do_IPI(struct pt_regs *regs); +/* + * Setup the SMP cpu_possible_map + */ +extern void smp_init_cpus(void); + /* * Move global data into per-processor storage. */