arm64: smp: Don't enter kernel with NULL stack pointer or task struct

Although SMP bringup is inherently racy, we can significantly reduce
the window during which secondary CPUs can unexpectedly enter the
kernel by sanity checking the 'stack' and 'task' fields of the
'secondary_data' structure. If the booting CPU gave up waiting for us,
then they will have been cleared to NULL and we should spin in a WFE; WFI
loop instead.

Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
Will Deacon 2019-08-27 14:36:38 +01:00
parent 0e1645557d
commit 5b1cfe3a0b
2 changed files with 9 additions and 0 deletions

View File

@ -724,14 +724,22 @@ __secondary_switched:
adr_l x0, secondary_data adr_l x0, secondary_data
ldr x1, [x0, #CPU_BOOT_STACK] // get secondary_data.stack ldr x1, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
cbz x1, __secondary_too_slow
mov sp, x1 mov sp, x1
ldr x2, [x0, #CPU_BOOT_TASK] ldr x2, [x0, #CPU_BOOT_TASK]
cbz x2, __secondary_too_slow
msr sp_el0, x2 msr sp_el0, x2
mov x29, #0 mov x29, #0
mov x30, #0 mov x30, #0
b secondary_start_kernel b secondary_start_kernel
ENDPROC(__secondary_switched) ENDPROC(__secondary_switched)
__secondary_too_slow:
wfe
wfi
b __secondary_too_slow
ENDPROC(__secondary_too_slow)
/* /*
* The booting CPU updates the failed status @__early_cpu_boot_status, * The booting CPU updates the failed status @__early_cpu_boot_status,
* with MMU turned off. * with MMU turned off.

View File

@ -136,6 +136,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
secondary_data.task = NULL; secondary_data.task = NULL;
secondary_data.stack = NULL; secondary_data.stack = NULL;
__flush_dcache_area(&secondary_data, sizeof(secondary_data));
status = READ_ONCE(secondary_data.status); status = READ_ONCE(secondary_data.status);
if (ret && status) { if (ret && status) {