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: a9d6915859 ("arm64/sme: Implement support for TPIDR2")
Cc: stable@vger.kernel.org
Acked-by: Will Deacon <will@kernel.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Wei Wang <wvw@google.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Wei Wang 2026-11-03 17:59:41 +00:00 committed by Catalin Marinas
parent 6628e7d4c6
commit beeec04046
2 changed files with 9 additions and 1 deletions

View File

@ -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
/*

View File

@ -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