From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1944) id EA2BF385E44E; Wed, 14 Feb 2024 15:06:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EA2BF385E44E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1707923197; bh=LkLBxC5tVg+alwV62GJCqFJZL8GqoyIJuLBq46Z2xbA=; h=From:To:Subject:Date:From; b=XWZXhfYjHHtaY55WTBVaktq90QfBlLlswYh2ZL/RFtFdGfMjJW2aluElMci9U8yfg xv2UbiJqyUXS8HDRXhrBxPZZ4WMQK16rCY66bfzURfdrrzBHKONvrBa9cgPla9qD/+ DXHO+JgVBDQt9iUd+ZINTQPipLaUbNo4d5gbgsr0= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Szabolcs Nagy To: glibc-cvs@sourceware.org Subject: [glibc/arm/gcs] aarch64: Add GCS support to longjmp X-Act-Checkin: glibc X-Git-Author: Szabolcs Nagy X-Git-Refname: refs/heads/arm/gcs X-Git-Oldrev: e6bc31c117194bfadcf10a6c90b6586800a33a11 X-Git-Newrev: c3274a8582b4915efea5a16558e730d362bea177 Message-Id: <20240214150637.EA2BF385E44E@sourceware.org> Date: Wed, 14 Feb 2024 15:06:37 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c3274a8582b4915efea5a16558e730d362bea177 commit c3274a8582b4915efea5a16558e730d362bea177 Author: Szabolcs Nagy Date: Thu Feb 23 08:54:04 2023 +0000 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. Diff: --- sysdeps/aarch64/__longjmp.S | 31 +++++++++++++++++++++++++++++++ sysdeps/aarch64/setjmp.S | 10 ++++++++++ 2 files changed, 41 insertions(+) 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)