[PATCH] arm: mediatek: fix secondary CPU boot on Thumb-2 kernels with Clang

Nick Desaulniers ndesaulniers at google.com
Wed Jul 22 14:03:31 PDT 2026


On Wed, Jul 22, 2026 at 10:25 AM Akari Tsuyukusa <akkun11.open at gmail.com> wrote:
>
> When building with CONFIG_THUMB2_KERNEL=y and Clang, secondary CPUs

Specifically, was LLVM=1 or CC=clang or something else used?

> fail to come online with "CPU1: failed to come online". The address
> written to the jump register has bit 0 set, causing the secondary CPU
> to start in Thumb mode.

Ah, yeah missing those is going to be a noticeable perf hit!

>
> secondary_startup_arm is ARM-mode code (.arm) and, on a Thumb-2 kernel,
> expects to be entered in ARM mode in order to switch to Thumb via the
> standard sequence at that label. Starting in Thumb mode causes the CPU
> to execute ARM instructions as Thumb, resulting in an immediate crash.
>
> Clear bit 0 of the entry address so the CPU always starts in ARM mode.

Thanks for the patch. Any idea why this isn't an issue for
GCC+GAS+BFD? Perhaps there's a difference in the LLVM tools that we
need to address?

There's definitely some difference between clang and GAS here.
https://github.com/llvm/llvm-project/issues/211376

I wonder if perhaps a better machine-agnostic assembler-agnostic
assembler-version-agnostic patch would be something like:

```
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f22c50d4bd41..687ee7063a73 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -383,6 +383,7 @@ ENDPROC(__create_page_tables)
 ENTRY(secondary_startup_arm)
  THUMB(        badr    r9, 1f          )       @ Kernel is entered in ARM.
  THUMB(        bx      r9              )       @ If this is a Thumb-2 kernel,
+ENDPROC(secondary_startup_arm)
  THUMB(        .thumb                  )       @ switch to Thumb now.
  THUMB(1:                      )
 ENTRY(secondary_startup)
@@ -429,7 +430,6 @@ ARM_BE8(eor r4, r4, r5)                     @
without using a temp reg.
                                                @ (return control reg)
        ret     r12
 ENDPROC(secondary_startup)
-ENDPROC(secondary_startup_arm)

 ENTRY(__secondary_switched)
 #if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)

```

Can you perhaps help test/verify that Akari?


>
> Tested on Lenovo YOGA Tablet 10 (Wi-Fi).
>
> Fixes: 0cda07001a94 ("ARM: mediatek: add smp bringup code")
> Assisted-by: DeepSeek:deepseek-v4-pro
> Cc: stable at vger.kernel.org
> Signed-off-by: Akari Tsuyukusa <akkun11.open at gmail.com>
> ---
>  arch/arm/mach-mediatek/platsmp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
> index 6b0943d95555..9a7c65fc3ae1 100644
> --- a/arch/arm/mach-mediatek/platsmp.c
> +++ b/arch/arm/mach-mediatek/platsmp.c
> @@ -124,7 +124,7 @@ static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone)
>          * write the address of slave startup address into the system-wide
>          * jump register
>          */
> -       writel_relaxed(__pa_symbol(secondary_startup_arm),
> +       writel_relaxed(__pa_symbol(secondary_startup_arm) & ~1,
>                         mtk_smp_base + mtk_smp_info->jump_reg);
>  }
>
> --
> 2.54.0
>


-- 
Thanks,
~Nick Desaulniers



More information about the Linux-mediatek mailing list