[PATCH 2/2] arm64: suspend: Save GCS state over suspend

From: Mark Brown

Date: Thu Nov 05 2026 - 11:48:33 EST


GCSCRE0_EL1 and GCSPR_EL0 are live registers for EL0 on systems with GCS
but are not saved and restored by cpu_do_suspend()/cpu_do_resume(). This
means that the task that initiated suspend can return to userspace with
UNKNOWN or incorrect values for GCSPR_EL0 and GCSCRE0_EL1 (many fields
in GCSCRE0_EL1 reset to 0). This will in turn lead to ongoing
corruption, including not restoring mode until a task with a different
GCS mode is run. Fix this by saving and restoring the values over
suspend.

This increases the size of struct cpu_suspend_ctx by 16 bytes.

Fixes: 5d8b172e7005 ("arm64: Add Kconfig for Guarded Control Stack (GCS)")
Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx
---
arch/arm64/include/asm/suspend.h | 2 +-
arch/arm64/mm/proc.S | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index eb9ce315f146..8e9c97aab15a 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 16
+#define NR_CTX_REGS 18
#define NR_CALLEE_SAVED_REGS 12

/*
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 664ea9e3b9ad..99aacf03367d 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -121,6 +121,12 @@ alternative_else_nop_endif
alternative_if ARM64_HAS_S1POE
mrs x2, REG_POR_EL0
str x2, [x0, #120]
+alternative_else_nop_endif
+alternative_if ARM64_HAS_GCS
+ mrs x2, REG_GCSPR_EL0
+ str x2, [x0, #128]
+ mrs x2, REG_GCSCRE0_EL1
+ str x2, [x0, #136]
alternative_else_nop_endif
ret
SYM_FUNC_END(cpu_do_suspend)
@@ -168,6 +174,12 @@ alternative_if ARM64_HAS_S1POE
ldr x2, [x0, #120]
msr REG_POR_EL0, x2
alternative_else_nop_endif
+alternative_if ARM64_HAS_GCS
+ ldr x2, [x0, #128]
+ msr REG_GCSPR_EL0, x2
+ ldr x2, [x0, #136]
+ msr REG_GCSCRE0_EL1, x2
+alternative_else_nop_endif

msr sctlr_el1, x12
set_this_cpu_offset x13

--
2.47.3