Commit 7bbb7940 authored by Russell King's avatar Russell King Committed by Russell King

[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: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent ba09cf2b
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/root_dev.h> #include <linux/root_dev.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smp.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/elf.h> #include <asm/elf.h>
...@@ -771,6 +772,10 @@ void __init setup_arch(char **cmdline_p) ...@@ -771,6 +772,10 @@ void __init setup_arch(char **cmdline_p)
paging_init(&meminfo, mdesc); paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc); request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_SMP
smp_init_cpus();
#endif
cpu_init(); cpu_init();
/* /*
......
...@@ -338,7 +338,6 @@ void __init smp_prepare_boot_cpu(void) ...@@ -338,7 +338,6 @@ void __init smp_prepare_boot_cpu(void)
per_cpu(cpu_data, cpu).idle = current; per_cpu(cpu_data, cpu).idle = current;
cpu_set(cpu, cpu_possible_map);
cpu_set(cpu, cpu_present_map); cpu_set(cpu, cpu_present_map);
cpu_set(cpu, cpu_online_map); cpu_set(cpu, cpu_online_map);
} }
......
...@@ -140,6 +140,18 @@ static void __init poke_milo(void) ...@@ -140,6 +140,18 @@ static void __init poke_milo(void)
mb(); 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) void __init smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = get_core_count(); unsigned int ncores = get_core_count();
...@@ -176,14 +188,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -176,14 +188,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
max_cpus = ncores; max_cpus = ncores;
/* /*
* Initialise the possible/present maps. * Initialise the present map, which describes the set of CPUs
* cpu_possible_map describes the set of CPUs which may be present * actually populated at the present time.
* cpu_present_map describes the set of CPUs populated
*/ */
for (i = 0; i < max_cpus; i++) { for (i = 0; i < max_cpus; i++)
cpu_set(i, cpu_possible_map);
cpu_set(i, cpu_present_map); cpu_set(i, cpu_present_map);
}
/* /*
* Do we need any more CPUs? If so, then let them know where * Do we need any more CPUs? If so, then let them know where
......
...@@ -143,6 +143,18 @@ static void __init poke_milo(void) ...@@ -143,6 +143,18 @@ static void __init poke_milo(void)
mb(); 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) void __init smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned int ncores = get_core_count(); unsigned int ncores = get_core_count();
...@@ -179,14 +191,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -179,14 +191,11 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
local_timer_setup(cpu); local_timer_setup(cpu);
/* /*
* Initialise the possible/present maps. * Initialise the present map, which describes the set of CPUs
* cpu_possible_map describes the set of CPUs which may be present * actually populated at the present time.
* cpu_present_map describes the set of CPUs populated
*/ */
for (i = 0; i < max_cpus; i++) { for (i = 0; i < max_cpus; i++)
cpu_set(i, cpu_possible_map);
cpu_set(i, cpu_present_map); cpu_set(i, cpu_present_map);
}
/* /*
* Do we need any more CPUs? If so, then let them know where * Do we need any more CPUs? If so, then let them know where
......
...@@ -41,6 +41,11 @@ extern void show_ipi_list(struct seq_file *p); ...@@ -41,6 +41,11 @@ extern void show_ipi_list(struct seq_file *p);
*/ */
asmlinkage void do_IPI(struct pt_regs *regs); 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. * Move global data into per-processor storage.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment