[PATCH 19/19] arm64: smp: Harden parallel CPU bringup against broken PSCI firmware
Will Deacon
will at kernel.org
Tue Sep 8 06:36:39 PDT 2026
On Mon, Sep 07, 2026 at 05:40:22PM +0100, Will Deacon wrote:
> Since firmware has occasionally been known to get things wrong, harden
> our parallel CPU bringup code against a PSCI implementation that passes
> the CPU_ON argument to an incorrect CPU.
>
> The primary CPU writes the MPIDR of the incoming CPU to the end of its
> task stack and this is then checked against the MPIDR_EL1 register
> during early kernel entry. A mismatch is reported via the existing
> failure reporting mechanism and the CPU is not brought online.
>
> Suggested-by: David Woodhouse <dwmw at amazon.co.uk>
> Signed-off-by: Will Deacon <will at kernel.org>
> ---
> arch/arm64/include/asm/smp.h | 4 +++-
> arch/arm64/kernel/asm-offsets.c | 1 +
> arch/arm64/kernel/head.S | 39 ++++++++++++++++++++++++++++-----
> arch/arm64/kernel/smp.c | 11 ++++++++--
> 4 files changed, 46 insertions(+), 9 deletions(-)
[...]
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index bec4bc1b12db..56deeb9673d6 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -192,11 +192,21 @@ SYM_CODE_END(preserve_boot_args)
> * its location in the task stack. We reserve the entire pt_regs space
> * for consistency with user tasks and kthreads.
> */
> - .macro init_cpu_task tsk, tmp1, tmp2
> + .macro init_cpu_task tsk, tmp1, tmp2, check_mpidr=
> msr sp_el0, \tsk
>
> ldr \tmp1, [\tsk, #TSK_STACK]
> - add sp, \tmp1, #THREAD_SIZE
> + mov sp, \tmp1
> + .ifnb \check_mpidr
> + mov_q \tmp1, MPIDR_HWID_BITMASK
> + mrs \tmp2, mpidr_el1
> + and \tmp2, \tmp2, \tmp1
> + ldr \tmp1, [sp]
> + sub \tmp1, \tmp1, \tmp2
> + cbnz \tmp1, __cpu_secondary_broken_psci_arg
> + .endif
> +
> + add sp, sp, #THREAD_SIZE
> sub sp, sp, #PT_REGS_SIZE
>
> stp xzr, xzr, [sp, #S_STACKFRAME]
> @@ -401,11 +411,12 @@ SYM_FUNC_START_LOCAL(__secondary_switched)
> cbnz x2, 1f
> adr_l x0, secondary_data
> ldr x2, [x0, #CPU_BOOT_TASK]
> - cbz x2, __secondary_too_slow
> -
> -1:
> init_cpu_task x2, x1, x3
> -
> + cbnz x2, 2f
> + b __secondary_too_slow
Bah, Sashiko points out that this is too late, as x2 has already been
dereferenced on the non-PSCI 0.2+ path. I'll rework this for v2.
Will
More information about the linux-arm-kernel
mailing list