diff options
| author | Wei Wang <wvw@google.com> | 2026-11-03 17:59:41 +0000 |
|---|---|---|
| committer | Catalin Marinas <catalin.marinas@arm.com> | 2026-11-04 18:21:16 +0000 |
| commit | beeec04046227eba42b7cc5ab32498aa43da9632 (patch) | |
| tree | ef326da43e491b52bdac0aa0ece2650d3c38e29c | |
| parent | 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4 (diff) | |
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 <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>
| -rw-r--r-- | arch/arm64/include/asm/suspend.h | 2 | ||||
| -rw-r--r-- | arch/arm64/mm/proc.S | 8 |
2 files changed, 9 insertions, 1 deletions
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 @@ -114,6 +114,10 @@ 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 |
