[v4,05/22] aarch64: Add GCS support to longjmp
Checks
Context |
Check |
Description |
redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Test passed
|
Commit Message
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
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.
---
sysdeps/aarch64/__longjmp.S | 30 ++++++++++++++++++++++++++++++
sysdeps/aarch64/setjmp.S | 10 ++++++++++
2 files changed, 40 insertions(+)
Comments
On 11/29/24 11:37 AM, Yury Khrustalev wrote:
> From: Szabolcs Nagy <szabolcs.nagy@arm.com>
>
> 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.
Doesn't expose any specific ABI, and can be committed immediately.
LGTM.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
> ---
> sysdeps/aarch64/__longjmp.S | 30 ++++++++++++++++++++++++++++++
> sysdeps/aarch64/setjmp.S | 10 ++++++++++
> 2 files changed, 40 insertions(+)
>
> diff --git a/sysdeps/aarch64/__longjmp.S b/sysdeps/aarch64/__longjmp.S
> index 7b6add751e..d8670d8995 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):
OK.
> +
> /* 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):
OK.
> +
> #ifdef PTR_MANGLE
> mov x4, sp
> PTR_MANGLE (5, 4, 3, 2)
@@ -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.
@@ -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)