From beeec04046227eba42b7cc5ab32498aa43da9632 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 3 Nov 2026 17:59:41 +0000 Subject: [PATCH] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend TPIDR2_EL0 is a live EL0 register on systems with SME, but cpu_do_suspend()/cpu_do_resume() don't preserve it. Its value is UNKNOWN after a warm reset, so the task that initiates suspend can return to userspace with a corrupted TPIDR2_EL0. Save and restore it alongside TPIDR_EL0 and TPIDRRO_EL0. The new slot fits in existing padding, so sizeof(struct cpu_suspend_ctx) is unchanged. Fixes: a9d691585950 ("arm64/sme: Implement support for TPIDR2") Cc: stable@vger.kernel.org Acked-by: Will Deacon Reviewed-by: Mark Brown Signed-off-by: Wei Wang Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/suspend.h | 2 +- arch/arm64/mm/proc.S | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h index e9ce68d50ba4..a5abf0615594 100644 --- a/arch/arm64/include/asm/suspend.h +++ b/arch/arm64/include/asm/suspend.h @@ -2,7 +2,7 @@ #ifndef __ASM_SUSPEND_H #define __ASM_SUSPEND_H -#define NR_CTX_REGS 14 +#define NR_CTX_REGS 15 #define NR_CALLEE_SAVED_REGS 12 /* diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 12aacc74f764..b1516630904d 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -113,6 +113,10 @@ SYM_FUNC_START(cpu_do_suspend) alternative_if ARM64_HAS_TCR2 mrs x2, REG_TCR2_EL1 str x2, [x0, #104] +alternative_else_nop_endif +alternative_if ARM64_SME + mrs_s x2, SYS_TPIDR2_EL0 + str x2, [x0, #112] alternative_else_nop_endif ret SYM_FUNC_END(cpu_do_suspend) @@ -152,6 +156,10 @@ alternative_if ARM64_HAS_TCR2 ldr x2, [x0, #104] msr REG_TCR2_EL1, x2 alternative_else_nop_endif +alternative_if ARM64_SME + ldr x2, [x0, #112] + msr_s SYS_TPIDR2_EL0, x2 +alternative_else_nop_endif msr sctlr_el1, x12 set_this_cpu_offset x13