diff options
author | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2023-02-23 08:54:04 +0000 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2024-02-02 15:58:10 +0000 |
commit | c3274a8582b4915efea5a16558e730d362bea177 (patch) | |
tree | 64a32b55342c1611b5bcf144098e9ce94b89ceee | |
parent | e6bc31c117194bfadcf10a6c90b6586800a33a11 (diff) | |
download | glibc-c3274a8582b4915efea5a16558e730d362bea177.tar.gz glibc-c3274a8582b4915efea5a16558e730d362bea177.tar.xz glibc-c3274a8582b4915efea5a16558e730d362bea177.zip |
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.
-rw-r--r-- | sysdeps/aarch64/__longjmp.S | 31 | ||||
-rw-r--r-- | sysdeps/aarch64/setjmp.S | 10 |
2 files changed, 41 insertions, 0 deletions
diff --git a/sysdeps/aarch64/__longjmp.S b/sysdeps/aarch64/__longjmp.S index 7b6add751e..ecd272262d 100644 --- a/sysdeps/aarch64/__longjmp.S +++ b/sysdeps/aarch64/__longjmp.S @@ -91,6 +91,37 @@ 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.eq L(gcs_switch) + b 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 43fdb1b2fb..f7ffccfaba 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) |