]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
aarch64: Add GCS support to longjmp
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Thu, 23 Feb 2023 08:54:04 +0000 (08:54 +0000)
committerYury Khrustalev <yury.khrustalev@arm.com>
Mon, 20 Jan 2025 09:22:41 +0000 (09:22 +0000)
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>
sysdeps/aarch64/__longjmp.S
sysdeps/aarch64/setjmp.S

index 2ef09112d7a1e55a3feef82a8e951b00b3e56f30..38efddbbae40483ea214c16da72815c39a52fcdf 100644 (file)
@@ -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.
 
index 4c968ae50632bdc20587c4fd34f993b122a0658a..b630ca099a8f37e61178a9186f97a483c04e6099 100644 (file)
@@ -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)