It's tempting to try running smp_run() more than once, but that won't currently work. In the meantime, let's fail better. Also, there's no reason to expose the structure in smp.h Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx> --- lib/arm/asm/smp.h | 8 -------- lib/arm/smp.c | 13 +++++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/arm/asm/smp.h b/lib/arm/asm/smp.h index 1d1cd7a29991..a3551a40e4c5 100644 --- a/lib/arm/asm/smp.h +++ b/lib/arm/asm/smp.h @@ -37,14 +37,6 @@ static inline void set_cpu_online(int cpu, bool online) } typedef void (*secondary_entry_fn)(void); - -/* secondary_data is reused for each cpu, so only boot one at a time */ -struct secondary_data { - void *stack; /* must be first member of struct */ - secondary_entry_fn entry; -}; -extern struct secondary_data secondary_data; - extern void smp_boot_secondary(int cpu, secondary_entry_fn entry); extern void smp_run(void (*func)(void)); diff --git a/lib/arm/smp.c b/lib/arm/smp.c index 8528aa454108..fe64ed410377 100644 --- a/lib/arm/smp.c +++ b/lib/arm/smp.c @@ -7,6 +7,7 @@ */ #include <libcflat.h> #include <asm/thread_info.h> +#include <asm/spinlock.h> #include <asm/cpumask.h> #include <asm/barrier.h> #include <asm/mmu.h> @@ -16,7 +17,13 @@ cpumask_t cpu_present_mask; cpumask_t cpu_online_mask; cpumask_t cpu_halted_mask; + +struct secondary_data { + void *stack; /* must be first member of struct */ + secondary_entry_fn entry; +}; struct secondary_data secondary_data; +static struct spinlock lock; secondary_entry_fn secondary_cinit(void) { @@ -45,6 +52,10 @@ void smp_boot_secondary(int cpu, secondary_entry_fn entry) { int ret; + spin_lock(&lock); + + assert_msg(!cpu_online(cpu), "CPU%d already boot once", cpu); + secondary_data.stack = thread_stack_alloc(); secondary_data.entry = entry; mmu_mark_disabled(cpu); @@ -53,6 +64,8 @@ void smp_boot_secondary(int cpu, secondary_entry_fn entry) while (!cpu_online(cpu)) wfe(); + + spin_unlock(&lock); } void secondary_halt(void) -- 2.9.4