aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2023-02-23 08:54:04 +0000
committerYury Khrustalev <yury.khrustalev@arm.com>2025-01-20 09:22:41 +0000
commit5ff5e7836e97a2d87778936b29c9607c120251be (patch)
tree1f7c452d4706f49efdd14c6e07d0659c70b874d5
parent13cbbb0cb29153bab099e040002e7cc78a0ceaaa (diff)
downloadglibc-5ff5e7836e97a2d87778936b29c9607c120251be.zip
glibc-5ff5e7836e97a2d87778936b29c9607c120251be.tar.gz
glibc-5ff5e7836e97a2d87778936b29c9607c120251be.tar.bz2
aarch64: Add GCS support to longjmp
This implementations ensures that longjmp across different stacks works: it scans for GCS cap token and switches GCS if necessary then the target GCSPR is restored with a GCSPOPM loop once the current GCSPR is on the same GCS. This makes longjmp linear time in the number of jumped over stack frames when GCS is enabled. Reviewed-by: Carlos O'Donell <carlos@redhat.com> Reviewed-by: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
-rw-r--r--sysdeps/aarch64/__longjmp.S30
-rw-r--r--sysdeps/aarch64/setjmp.S10
2 files changed, 40 insertions, 0 deletions
diff --git a/sysdeps/aarch64/__longjmp.S b/sysdeps/aarch64/__longjmp.S
index 2ef0911..38efddb 100644
--- a/sysdeps/aarch64/__longjmp.S
+++ b/sysdeps/aarch64/__longjmp.S
@@ -91,6 +91,36 @@ ENTRY (__longjmp)
ldp d12, d13, [x0, #JB_D12<<3]
ldp d14, d15, [x0, #JB_D14<<3]
+ /* GCS support. */
+ mov x16, 1
+ CHKFEAT_X16
+ tbnz x16, 0, L(gcs_done)
+ MRS_GCSPR (x2)
+ ldr x3, [x0, #JB_GCSPR]
+ mov x4, x3
+ /* x2: GCSPR now. x3, x4: target GCSPR. x5, x6: tmp regs. */
+L(gcs_scan):
+ cmp x2, x4
+ b.eq L(gcs_pop)
+ sub x4, x4, 8
+ /* Check for a cap token. */
+ ldr x5, [x4]
+ and x6, x4, 0xfffffffffffff000
+ orr x6, x6, 1
+ cmp x5, x6
+ b.ne L(gcs_scan)
+L(gcs_switch):
+ add x2, x4, 8
+ GCSSS1 (x4)
+ GCSSS2 (xzr)
+L(gcs_pop):
+ cmp x2, x3
+ b.eq L(gcs_done)
+ GCSPOPM (xzr)
+ add x2, x2, 8
+ b L(gcs_pop)
+L(gcs_done):
+
/* Originally this was implemented with a series of
.cfi_restore() directives.
diff --git a/sysdeps/aarch64/setjmp.S b/sysdeps/aarch64/setjmp.S
index 4c968ae..b630ca0 100644
--- a/sysdeps/aarch64/setjmp.S
+++ b/sysdeps/aarch64/setjmp.S
@@ -57,6 +57,16 @@ ENTRY (__sigsetjmp)
stp d10, d11, [x0, #JB_D10<<3]
stp d12, d13, [x0, #JB_D12<<3]
stp d14, d15, [x0, #JB_D14<<3]
+
+ /* GCS support. */
+ mov x16, 1
+ CHKFEAT_X16
+ tbnz x16, 0, L(gcs_done)
+ MRS_GCSPR (x2)
+ add x2, x2, 8 /* GCS state right after setjmp returns. */
+ str x2, [x0, #JB_GCSPR]
+L(gcs_done):
+
#ifdef PTR_MANGLE
mov x4, sp
PTR_MANGLE (5, 4, 3, 2)