public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/arm/morello/main] aarch64: morello: add purecap ucontext support
@ 2022-10-27 13:57 Szabolcs Nagy
0 siblings, 0 replies; 4+ messages in thread
From: Szabolcs Nagy @ 2022-10-27 13:57 UTC (permalink / raw)
To: glibc-cvs
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=45f35bca7d80322d25f16b4794f812f2e9c7f936
commit 45f35bca7d80322d25f16b4794f812f2e9c7f936
Author: Carlos Eduardo Seo <carlos.seo@arm.com>
Date: Thu May 27 17:49:20 2021 -0300
aarch64: morello: add purecap ucontext support
Adjust ucontext layout for purecap ABI and add make/get/set/swapcontext
implementations accordingly.
Note: mcontext layout follows the linux sigcontext struct, in userspace
*context functions rely on the c registers stored in the extension area
and ignore the mcontext fields for x registers.
Diff:
---
sysdeps/unix/sysv/linux/aarch64/bits/procfs.h | 5 +
.../unix/sysv/linux/aarch64/morello/getcontext.S | 121 +++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/makecontext.c | 80 +++++++++++++
.../unix/sysv/linux/aarch64/morello/setcontext.S | 133 +++++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/swapcontext.S | 120 +++++++++++++++++++
sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h | 4 +
sysdeps/unix/sysv/linux/aarch64/sys/user.h | 10 ++
.../unix/sysv/linux/aarch64/ucontext-internal.h | 5 +
sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym | 15 +++
9 files changed, 493 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
index 154fb95e66..596b95e333 100644
--- a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
@@ -33,3 +33,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
/* Register set for the floating-point registers. */
typedef struct user_fpsimd_struct elf_fpregset_t;
+
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Register set for the capability registers. */
+typedef struct user_morello_struct elf_cregset_t;
+#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
new file mode 100644
index 0000000000..217ca28285
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
@@ -0,0 +1,121 @@
+/* Save current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int getcontext (ucontext_t *ucp)
+
+ Returns 0 on success -1 and errno on failure.
+ */
+
+ .text
+
+ENTRY(__getcontext)
+ /* For Morello, we will save only the capability registers. These are saved
+ in a special area in the context extension block after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ /* The saved context will return to the getcontext() call point
+ with a return value of 0 */
+ str czr, [c10, 0 * SZCREG]
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+
+ /* Place LR into the saved PC, this will ensure that when
+ switching to this saved context with setcontext() control
+ will pass back to the caller of getcontext(), we have
+ already arrange to return the appropriate return value in x0
+ above. */
+ str c30, [c9, oPCC]
+
+ /* Save the current CSP */
+ mov c2, csp
+ str c2, [c9, oCSP]
+
+ /* Initialize the pstate. */
+ str xzr, [c0, oPSTATE]
+
+ /* Figure out where to place the first context extension
+ block. */
+ add c2, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c2, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c2, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ stp q8, q9, [c3], # 2 * SZVREG
+ stp q10, q11, [c3], # 2 * SZVREG
+ stp q12, q13, [c3], # 2 * SZVREG
+ stp q14, q15, [c3], # 2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ mrs x4, fpsr
+ str w4, [c3]
+
+ mrs x4, fpcr
+ str w4, [c3, oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c2, c2, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c2, #oHEAD + oMAGIC]
+ str wzr, [c2, #oHEAD + oSIZE]
+
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ /* Return 0 for success */
+ mov x0, 0
+ RET
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+
+ PSEUDO_END (__getcontext)
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
new file mode 100644
index 0000000000..3bbfe85887
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
@@ -0,0 +1,80 @@
+/* Create new context.
+ Copyright (C) 2002-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+#include <ucontext.h>
+#include <asm/sigcontext.h>
+#include "ucontext-internal.h"
+
+/* makecontext sets up a stack and the registers for the
+ user context. The stack looks like this:
+
+ +-----------------------+
+ | padding as required |
+ +-----------------------+
+ sp -> | parameter 7-n |
+ +-----------------------+
+
+ The registers are set up like this:
+ %c0 .. %c7: parameter 1 to 8
+ %c19 : uc_link
+ %csp : stack pointer.
+*/
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __startcontext (void);
+ uint64_t *sp;
+ va_list ap;
+ int i;
+ struct morello_context *c_context;
+
+ sp = (uint64_t *)
+ ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+ /* Allocate stack arguments. */
+ sp -= argc < 8 ? 0 : argc - 8;
+
+ /* Keep the stack aligned. */
+ sp = (uint64_t *) (((uintptr_t) sp) & -16L);
+
+ c_context = (void *) (ucp->uc_mcontext.__reserved
+ + sizeof (struct fpsimd_context));
+
+ c_context->cregs[19] = (uintptr_t) ucp->uc_link;
+ c_context->csp = (uintptr_t) sp;
+ c_context->pcc = (uintptr_t) func;
+ c_context->cregs[29] = (uintptr_t) 0;
+ c_context->cregs[30] = (uintptr_t) &__startcontext;
+
+ va_start (ap, argc);
+ for (i = 0; i < argc; ++i)
+ if (i < 8)
+ c_context->cregs[i] = va_arg (ap, uint64_t);
+ else
+ sp[i - 8] = va_arg (ap, uint64_t);
+
+ va_end (ap);
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
new file mode 100644
index 0000000000..3556d783fc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
@@ -0,0 +1,133 @@
+/* Set current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ .text
+
+ENTRY (__setcontext)
+ /* Save a copy of UCP. */
+ mov c9, c0
+
+ /* Set the signal mask with
+ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */
+ mov x0, #SIG_SETMASK
+ add c1, c9, #UCONTEXT_SIGMASK
+ mov x2, #0
+ mov x3, #_NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbz x0, 1f
+ b C_SYMBOL_NAME (__syscall_error)
+1:
+ /* Restore the capability registers. For Morello, they are saved after the
+ FPSIMD context. */
+ mov c0, c9
+ cfi_def_cfa (c0, 0)
+ cfi_offset (c18, oC0 + 18 * SZCREG)
+ cfi_offset (c19, oC0 + 19 * SZCREG)
+ cfi_offset (c20, oC0 + 20 * SZCREG)
+ cfi_offset (c21, oC0 + 21 * SZCREG)
+ cfi_offset (c22, oC0 + 22 * SZCREG)
+ cfi_offset (c23, oC0 + 23 * SZCREG)
+ cfi_offset (c24, oC0 + 24 * SZCREG)
+ cfi_offset (c25, oC0 + 25 * SZCREG)
+ cfi_offset (c26, oC0 + 26 * SZCREG)
+ cfi_offset (c27, oC0 + 27 * SZCREG)
+ cfi_offset (c28, oC0 + 28 * SZCREG)
+ cfi_offset (c29, oC0 + 29 * SZCREG)
+ cfi_offset (c30, oC0 + 30 * SZCREG)
+
+ cfi_offset ( d8, oV0 + 8 * SZVREG)
+ cfi_offset ( d9, oV0 + 9 * SZVREG)
+ cfi_offset (d10, oV0 + 10 * SZVREG)
+ cfi_offset (d11, oV0 + 11 * SZVREG)
+ cfi_offset (d12, oV0 + 12 * SZVREG)
+ cfi_offset (d13, oV0 + 13 * SZVREG)
+ cfi_offset (d14, oV0 + 14 * SZVREG)
+ cfi_offset (d15, oV0 + 15 * SZVREG)
+
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+ add c10, c9, #oC0
+ ldp c18, c19, [c10, 18 * SZCREG]
+ ldp c20, c21, [c10, 20 * SZCREG]
+ ldp c22, c23, [c10, 22 * SZCREG]
+ ldp c24, c25, [c10, 24 * SZCREG]
+ ldp c26, c27, [c10, 26 * SZCREG]
+ ldp c28, c29, [c10, 28 * SZCREG]
+ ldr c30, [c10, 30 * SZCREG]
+ ldr c2, [c9, oCSP]
+ mov csp, c2
+
+ /* Check for FP SIMD context. We don't support restoring
+ contexts created by the kernel, so this context must have
+ been created by getcontext. Hence we can rely on the
+ first extension block being the FP SIMD context. */
+ add c2, c0, #oEXTENSION
+
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ ldr w1, [c2, #oHEAD + oMAGIC]
+ cmp w1, w3
+ b.ne 2f
+
+ /* Restore the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ ldp q8, q9, [c3], #2 * SZVREG
+ ldp q10, q11, [c3], #2 * SZVREG
+ ldp q12, q13, [c3], #2 * SZVREG
+ ldp q14, q15, [c3], #2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ ldr w4, [c3]
+ msr fpsr, x4
+
+ ldr w4, [c3, oFPCR - oFPSR]
+ msr fpcr, x4
+
+2:
+ ldr c16, [c9, oPCC]
+ /* Restore arg registers. */
+ ldp c2, c3, [c10, 2 * SZCREG]
+ ldp c4, c5, [c10, 4 * SZCREG]
+ ldp c6, c7, [c10, 6 * SZCREG]
+ ldp c0, c1, [c10, 0 * SZCREG]
+ /* Jump to the new pc value. */
+ br c16
+PSEUDO_END (__setcontext)
+weak_alias (__setcontext, setcontext)
+
+ENTRY (__startcontext)
+ mov c0, c19
+ cbnz x0, __setcontext
+1: b HIDDEN_JUMPTARGET (exit)
+END (__startcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
new file mode 100644
index 0000000000..90e4eca413
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
@@ -0,0 +1,120 @@
+/* Modify saved context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ .text
+ENTRY(__swapcontext)
+ /* Set the value returned when swapcontext() returns in this context.
+ And set up x1 to become the return address of the caller, so we
+ can return there with a normal RET instead of an indirect jump. */
+
+ /* For Morello, the capability registers are located in after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ stp czr, c30, [c10, 0 * SZCREG]
+ /* Arrange the oucp context to return to 2f. */
+ adr c30, 2f
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+ str c30, [c9, oPCC]
+ mov c11, csp
+ str c11, [c9, oCSP]
+
+ /* Figure out where to place the fpsimd context extension
+ block. */
+ add c9, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c9, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c9, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c10, c9, #oV0 + 8 * SZVREG
+ stp q8, q9, [c10], #2 * SZVREG
+ stp q10, q11, [c10], #2 * SZVREG
+ stp q12, q13, [c10], #2 * SZVREG
+ stp q14, q15, [c10], #2 * SZVREG
+
+ add c10, c9, #oFPSR
+ mrs x4, fpsr
+ str w4, [c10, #oFPSR - oFPSR]
+ mrs x4, fpcr
+ str w4, [c10, #oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c9, c9, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c9, #oHEAD + oMAGIC]
+ str wzr, [c9, #oHEAD + oSIZE]
+
+ /* Preserve ucp. */
+ mov c11, c1
+
+ /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
+ _NSIG8) */
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ mov c15, c30
+ mov c0, c11
+ bl JUMPTARGET (__setcontext)
+ mov c30, c15
+ RET
+
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+2:
+ /* The oucp context is restored here via an indirect branch,
+ x1 must be restored too which has the real return address. */
+ mov c30, c1
+ RET
+PSEUDO_END (__swapcontext)
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
index fe91db68e8..cd39a2272b 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
@@ -43,6 +43,10 @@ typedef elf_gregset_t gregset_t;
/* Structure to describe FPU registers. */
typedef elf_fpregset_t fpregset_t;
+# ifdef __CHERI_PURE_CAPABILITY__
+/* Structure to describe capability registers. */
+typedef elf_cregset_t cregset_t;
+# endif
#endif
/* Context to describe whole processor state. This only describes
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/user.h b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
index 32fbfd5f1a..e228838bc7 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/user.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
@@ -34,4 +34,14 @@ struct user_fpsimd_struct
unsigned int fpcr;
};
+# ifdef __CHERI_PURE_CAPABILITY__
+struct user_morello_struct
+{
+ __uintcap_t cregs[31];
+ __uintcap_t csp;
+ __uintcap_t rcsp;
+ __uintcap_t pcc;
+};
+# endif
+
#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
index 685d41ca04..429a4c1035 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
@@ -23,6 +23,11 @@
/* Size of an X regiser in bytes. */
#define SZREG 8
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Size of a C register in bytes. */
+# define SZCREG 16
+#endif
+
/* Size of a V register in bytes. */
#define SZVREG 16
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
index ab3930c173..78022326af 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
@@ -18,6 +18,9 @@ RT_SIGFRAME_UCONTEXT rt_sigframe (uc)
RT_SIGFRAME_SIZE sizeof (struct kernel_rt_sigframe)
FPSIMD_CONTEXT_SIZE sizeof (struct fpsimd_context)
+#ifdef __CHERI_PURE_CAPABILITY__
+MORELLO_CONTEXT_SIZE sizeof (struct morello_context)
+#endif
#define ucontext(member) offsetof (ucontext_t, member)
#define stack(member) ucontext (uc_stack.member)
@@ -53,3 +56,15 @@ oMAGIC aarch64_ctx (magic)
oSIZE aarch64_ctx (size)
FPSIMD_MAGIC
+
+#ifdef __CHERI_PURE_CAPABILITY__
+#define morello_context(member) offsetof (struct morello_context, member)
+
+oCHEAD morello_context (head)
+oC0 morello_context (cregs)
+oCSP morello_context (csp)
+oRCSP morello_context (rcsp)
+oPCC morello_context (pcc)
+
+MORELLO_MAGIC
+#endif
^ permalink raw reply [flat|nested] 4+ messages in thread
* [glibc/arm/morello/main] aarch64: morello: add purecap ucontext support
@ 2022-11-23 14:47 Szabolcs Nagy
0 siblings, 0 replies; 4+ messages in thread
From: Szabolcs Nagy @ 2022-11-23 14:47 UTC (permalink / raw)
To: glibc-cvs
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2f33e8ec62cf2a9b5715948edd2b5bb553fd4ac8
commit 2f33e8ec62cf2a9b5715948edd2b5bb553fd4ac8
Author: Carlos Eduardo Seo <carlos.seo@arm.com>
Date: Thu May 27 17:49:20 2021 -0300
aarch64: morello: add purecap ucontext support
Adjust ucontext layout for purecap ABI and add make/get/set/swapcontext
implementations accordingly.
Note: mcontext layout follows the linux sigcontext struct, in userspace
*context functions rely on the c registers stored in the extension area
and ignore the mcontext fields for x registers.
Diff:
---
sysdeps/unix/sysv/linux/aarch64/bits/procfs.h | 5 +
.../unix/sysv/linux/aarch64/morello/getcontext.S | 121 +++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/makecontext.c | 80 +++++++++++++
.../unix/sysv/linux/aarch64/morello/setcontext.S | 133 +++++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/swapcontext.S | 120 +++++++++++++++++++
sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h | 4 +
sysdeps/unix/sysv/linux/aarch64/sys/user.h | 10 ++
.../unix/sysv/linux/aarch64/ucontext-internal.h | 5 +
sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym | 15 +++
9 files changed, 493 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
index 154fb95e66..596b95e333 100644
--- a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
@@ -33,3 +33,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
/* Register set for the floating-point registers. */
typedef struct user_fpsimd_struct elf_fpregset_t;
+
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Register set for the capability registers. */
+typedef struct user_morello_struct elf_cregset_t;
+#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
new file mode 100644
index 0000000000..217ca28285
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
@@ -0,0 +1,121 @@
+/* Save current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int getcontext (ucontext_t *ucp)
+
+ Returns 0 on success -1 and errno on failure.
+ */
+
+ .text
+
+ENTRY(__getcontext)
+ /* For Morello, we will save only the capability registers. These are saved
+ in a special area in the context extension block after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ /* The saved context will return to the getcontext() call point
+ with a return value of 0 */
+ str czr, [c10, 0 * SZCREG]
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+
+ /* Place LR into the saved PC, this will ensure that when
+ switching to this saved context with setcontext() control
+ will pass back to the caller of getcontext(), we have
+ already arrange to return the appropriate return value in x0
+ above. */
+ str c30, [c9, oPCC]
+
+ /* Save the current CSP */
+ mov c2, csp
+ str c2, [c9, oCSP]
+
+ /* Initialize the pstate. */
+ str xzr, [c0, oPSTATE]
+
+ /* Figure out where to place the first context extension
+ block. */
+ add c2, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c2, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c2, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ stp q8, q9, [c3], # 2 * SZVREG
+ stp q10, q11, [c3], # 2 * SZVREG
+ stp q12, q13, [c3], # 2 * SZVREG
+ stp q14, q15, [c3], # 2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ mrs x4, fpsr
+ str w4, [c3]
+
+ mrs x4, fpcr
+ str w4, [c3, oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c2, c2, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c2, #oHEAD + oMAGIC]
+ str wzr, [c2, #oHEAD + oSIZE]
+
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ /* Return 0 for success */
+ mov x0, 0
+ RET
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+
+ PSEUDO_END (__getcontext)
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
new file mode 100644
index 0000000000..3bbfe85887
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
@@ -0,0 +1,80 @@
+/* Create new context.
+ Copyright (C) 2002-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+#include <ucontext.h>
+#include <asm/sigcontext.h>
+#include "ucontext-internal.h"
+
+/* makecontext sets up a stack and the registers for the
+ user context. The stack looks like this:
+
+ +-----------------------+
+ | padding as required |
+ +-----------------------+
+ sp -> | parameter 7-n |
+ +-----------------------+
+
+ The registers are set up like this:
+ %c0 .. %c7: parameter 1 to 8
+ %c19 : uc_link
+ %csp : stack pointer.
+*/
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __startcontext (void);
+ uint64_t *sp;
+ va_list ap;
+ int i;
+ struct morello_context *c_context;
+
+ sp = (uint64_t *)
+ ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+ /* Allocate stack arguments. */
+ sp -= argc < 8 ? 0 : argc - 8;
+
+ /* Keep the stack aligned. */
+ sp = (uint64_t *) (((uintptr_t) sp) & -16L);
+
+ c_context = (void *) (ucp->uc_mcontext.__reserved
+ + sizeof (struct fpsimd_context));
+
+ c_context->cregs[19] = (uintptr_t) ucp->uc_link;
+ c_context->csp = (uintptr_t) sp;
+ c_context->pcc = (uintptr_t) func;
+ c_context->cregs[29] = (uintptr_t) 0;
+ c_context->cregs[30] = (uintptr_t) &__startcontext;
+
+ va_start (ap, argc);
+ for (i = 0; i < argc; ++i)
+ if (i < 8)
+ c_context->cregs[i] = va_arg (ap, uint64_t);
+ else
+ sp[i - 8] = va_arg (ap, uint64_t);
+
+ va_end (ap);
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
new file mode 100644
index 0000000000..3556d783fc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
@@ -0,0 +1,133 @@
+/* Set current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ .text
+
+ENTRY (__setcontext)
+ /* Save a copy of UCP. */
+ mov c9, c0
+
+ /* Set the signal mask with
+ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */
+ mov x0, #SIG_SETMASK
+ add c1, c9, #UCONTEXT_SIGMASK
+ mov x2, #0
+ mov x3, #_NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbz x0, 1f
+ b C_SYMBOL_NAME (__syscall_error)
+1:
+ /* Restore the capability registers. For Morello, they are saved after the
+ FPSIMD context. */
+ mov c0, c9
+ cfi_def_cfa (c0, 0)
+ cfi_offset (c18, oC0 + 18 * SZCREG)
+ cfi_offset (c19, oC0 + 19 * SZCREG)
+ cfi_offset (c20, oC0 + 20 * SZCREG)
+ cfi_offset (c21, oC0 + 21 * SZCREG)
+ cfi_offset (c22, oC0 + 22 * SZCREG)
+ cfi_offset (c23, oC0 + 23 * SZCREG)
+ cfi_offset (c24, oC0 + 24 * SZCREG)
+ cfi_offset (c25, oC0 + 25 * SZCREG)
+ cfi_offset (c26, oC0 + 26 * SZCREG)
+ cfi_offset (c27, oC0 + 27 * SZCREG)
+ cfi_offset (c28, oC0 + 28 * SZCREG)
+ cfi_offset (c29, oC0 + 29 * SZCREG)
+ cfi_offset (c30, oC0 + 30 * SZCREG)
+
+ cfi_offset ( d8, oV0 + 8 * SZVREG)
+ cfi_offset ( d9, oV0 + 9 * SZVREG)
+ cfi_offset (d10, oV0 + 10 * SZVREG)
+ cfi_offset (d11, oV0 + 11 * SZVREG)
+ cfi_offset (d12, oV0 + 12 * SZVREG)
+ cfi_offset (d13, oV0 + 13 * SZVREG)
+ cfi_offset (d14, oV0 + 14 * SZVREG)
+ cfi_offset (d15, oV0 + 15 * SZVREG)
+
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+ add c10, c9, #oC0
+ ldp c18, c19, [c10, 18 * SZCREG]
+ ldp c20, c21, [c10, 20 * SZCREG]
+ ldp c22, c23, [c10, 22 * SZCREG]
+ ldp c24, c25, [c10, 24 * SZCREG]
+ ldp c26, c27, [c10, 26 * SZCREG]
+ ldp c28, c29, [c10, 28 * SZCREG]
+ ldr c30, [c10, 30 * SZCREG]
+ ldr c2, [c9, oCSP]
+ mov csp, c2
+
+ /* Check for FP SIMD context. We don't support restoring
+ contexts created by the kernel, so this context must have
+ been created by getcontext. Hence we can rely on the
+ first extension block being the FP SIMD context. */
+ add c2, c0, #oEXTENSION
+
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ ldr w1, [c2, #oHEAD + oMAGIC]
+ cmp w1, w3
+ b.ne 2f
+
+ /* Restore the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ ldp q8, q9, [c3], #2 * SZVREG
+ ldp q10, q11, [c3], #2 * SZVREG
+ ldp q12, q13, [c3], #2 * SZVREG
+ ldp q14, q15, [c3], #2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ ldr w4, [c3]
+ msr fpsr, x4
+
+ ldr w4, [c3, oFPCR - oFPSR]
+ msr fpcr, x4
+
+2:
+ ldr c16, [c9, oPCC]
+ /* Restore arg registers. */
+ ldp c2, c3, [c10, 2 * SZCREG]
+ ldp c4, c5, [c10, 4 * SZCREG]
+ ldp c6, c7, [c10, 6 * SZCREG]
+ ldp c0, c1, [c10, 0 * SZCREG]
+ /* Jump to the new pc value. */
+ br c16
+PSEUDO_END (__setcontext)
+weak_alias (__setcontext, setcontext)
+
+ENTRY (__startcontext)
+ mov c0, c19
+ cbnz x0, __setcontext
+1: b HIDDEN_JUMPTARGET (exit)
+END (__startcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
new file mode 100644
index 0000000000..90e4eca413
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
@@ -0,0 +1,120 @@
+/* Modify saved context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ .text
+ENTRY(__swapcontext)
+ /* Set the value returned when swapcontext() returns in this context.
+ And set up x1 to become the return address of the caller, so we
+ can return there with a normal RET instead of an indirect jump. */
+
+ /* For Morello, the capability registers are located in after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ stp czr, c30, [c10, 0 * SZCREG]
+ /* Arrange the oucp context to return to 2f. */
+ adr c30, 2f
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+ str c30, [c9, oPCC]
+ mov c11, csp
+ str c11, [c9, oCSP]
+
+ /* Figure out where to place the fpsimd context extension
+ block. */
+ add c9, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c9, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c9, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c10, c9, #oV0 + 8 * SZVREG
+ stp q8, q9, [c10], #2 * SZVREG
+ stp q10, q11, [c10], #2 * SZVREG
+ stp q12, q13, [c10], #2 * SZVREG
+ stp q14, q15, [c10], #2 * SZVREG
+
+ add c10, c9, #oFPSR
+ mrs x4, fpsr
+ str w4, [c10, #oFPSR - oFPSR]
+ mrs x4, fpcr
+ str w4, [c10, #oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c9, c9, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c9, #oHEAD + oMAGIC]
+ str wzr, [c9, #oHEAD + oSIZE]
+
+ /* Preserve ucp. */
+ mov c11, c1
+
+ /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
+ _NSIG8) */
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ mov c15, c30
+ mov c0, c11
+ bl JUMPTARGET (__setcontext)
+ mov c30, c15
+ RET
+
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+2:
+ /* The oucp context is restored here via an indirect branch,
+ x1 must be restored too which has the real return address. */
+ mov c30, c1
+ RET
+PSEUDO_END (__swapcontext)
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
index fe91db68e8..cd39a2272b 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
@@ -43,6 +43,10 @@ typedef elf_gregset_t gregset_t;
/* Structure to describe FPU registers. */
typedef elf_fpregset_t fpregset_t;
+# ifdef __CHERI_PURE_CAPABILITY__
+/* Structure to describe capability registers. */
+typedef elf_cregset_t cregset_t;
+# endif
#endif
/* Context to describe whole processor state. This only describes
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/user.h b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
index 32fbfd5f1a..e228838bc7 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/user.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
@@ -34,4 +34,14 @@ struct user_fpsimd_struct
unsigned int fpcr;
};
+# ifdef __CHERI_PURE_CAPABILITY__
+struct user_morello_struct
+{
+ __uintcap_t cregs[31];
+ __uintcap_t csp;
+ __uintcap_t rcsp;
+ __uintcap_t pcc;
+};
+# endif
+
#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
index 685d41ca04..429a4c1035 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
@@ -23,6 +23,11 @@
/* Size of an X regiser in bytes. */
#define SZREG 8
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Size of a C register in bytes. */
+# define SZCREG 16
+#endif
+
/* Size of a V register in bytes. */
#define SZVREG 16
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
index ab3930c173..78022326af 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
@@ -18,6 +18,9 @@ RT_SIGFRAME_UCONTEXT rt_sigframe (uc)
RT_SIGFRAME_SIZE sizeof (struct kernel_rt_sigframe)
FPSIMD_CONTEXT_SIZE sizeof (struct fpsimd_context)
+#ifdef __CHERI_PURE_CAPABILITY__
+MORELLO_CONTEXT_SIZE sizeof (struct morello_context)
+#endif
#define ucontext(member) offsetof (ucontext_t, member)
#define stack(member) ucontext (uc_stack.member)
@@ -53,3 +56,15 @@ oMAGIC aarch64_ctx (magic)
oSIZE aarch64_ctx (size)
FPSIMD_MAGIC
+
+#ifdef __CHERI_PURE_CAPABILITY__
+#define morello_context(member) offsetof (struct morello_context, member)
+
+oCHEAD morello_context (head)
+oC0 morello_context (cregs)
+oCSP morello_context (csp)
+oRCSP morello_context (rcsp)
+oPCC morello_context (pcc)
+
+MORELLO_MAGIC
+#endif
^ permalink raw reply [flat|nested] 4+ messages in thread
* [glibc/arm/morello/main] aarch64: morello: add purecap ucontext support
@ 2022-10-26 15:18 Szabolcs Nagy
0 siblings, 0 replies; 4+ messages in thread
From: Szabolcs Nagy @ 2022-10-26 15:18 UTC (permalink / raw)
To: glibc-cvs
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9eb64fc2d4cbc4186f5693258ade72398e6de397
commit 9eb64fc2d4cbc4186f5693258ade72398e6de397
Author: Carlos Eduardo Seo <carlos.seo@arm.com>
Date: Thu May 27 17:49:20 2021 -0300
aarch64: morello: add purecap ucontext support
Adjust ucontext layout for purecap ABI and add make/get/set/swapcontext
implementations accordingly.
Note: mcontext layout follows the linux sigcontext struct, in userspace
*context functions rely on the c registers stored in the extension area
and ignore the mcontext fields for x registers.
Diff:
---
sysdeps/unix/sysv/linux/aarch64/bits/procfs.h | 5 +
.../unix/sysv/linux/aarch64/morello/getcontext.S | 121 +++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/makecontext.c | 80 +++++++++++++
.../unix/sysv/linux/aarch64/morello/setcontext.S | 133 +++++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/swapcontext.S | 120 +++++++++++++++++++
sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h | 4 +
sysdeps/unix/sysv/linux/aarch64/sys/user.h | 10 ++
.../unix/sysv/linux/aarch64/ucontext-internal.h | 5 +
sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym | 15 +++
9 files changed, 493 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
index 154fb95e66..596b95e333 100644
--- a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
@@ -33,3 +33,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
/* Register set for the floating-point registers. */
typedef struct user_fpsimd_struct elf_fpregset_t;
+
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Register set for the capability registers. */
+typedef struct user_morello_struct elf_cregset_t;
+#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
new file mode 100644
index 0000000000..217ca28285
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
@@ -0,0 +1,121 @@
+/* Save current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int getcontext (ucontext_t *ucp)
+
+ Returns 0 on success -1 and errno on failure.
+ */
+
+ .text
+
+ENTRY(__getcontext)
+ /* For Morello, we will save only the capability registers. These are saved
+ in a special area in the context extension block after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ /* The saved context will return to the getcontext() call point
+ with a return value of 0 */
+ str czr, [c10, 0 * SZCREG]
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+
+ /* Place LR into the saved PC, this will ensure that when
+ switching to this saved context with setcontext() control
+ will pass back to the caller of getcontext(), we have
+ already arrange to return the appropriate return value in x0
+ above. */
+ str c30, [c9, oPCC]
+
+ /* Save the current CSP */
+ mov c2, csp
+ str c2, [c9, oCSP]
+
+ /* Initialize the pstate. */
+ str xzr, [c0, oPSTATE]
+
+ /* Figure out where to place the first context extension
+ block. */
+ add c2, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c2, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c2, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ stp q8, q9, [c3], # 2 * SZVREG
+ stp q10, q11, [c3], # 2 * SZVREG
+ stp q12, q13, [c3], # 2 * SZVREG
+ stp q14, q15, [c3], # 2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ mrs x4, fpsr
+ str w4, [c3]
+
+ mrs x4, fpcr
+ str w4, [c3, oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c2, c2, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c2, #oHEAD + oMAGIC]
+ str wzr, [c2, #oHEAD + oSIZE]
+
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ /* Return 0 for success */
+ mov x0, 0
+ RET
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+
+ PSEUDO_END (__getcontext)
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
new file mode 100644
index 0000000000..3bbfe85887
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
@@ -0,0 +1,80 @@
+/* Create new context.
+ Copyright (C) 2002-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+#include <ucontext.h>
+#include <asm/sigcontext.h>
+#include "ucontext-internal.h"
+
+/* makecontext sets up a stack and the registers for the
+ user context. The stack looks like this:
+
+ +-----------------------+
+ | padding as required |
+ +-----------------------+
+ sp -> | parameter 7-n |
+ +-----------------------+
+
+ The registers are set up like this:
+ %c0 .. %c7: parameter 1 to 8
+ %c19 : uc_link
+ %csp : stack pointer.
+*/
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __startcontext (void);
+ uint64_t *sp;
+ va_list ap;
+ int i;
+ struct morello_context *c_context;
+
+ sp = (uint64_t *)
+ ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+ /* Allocate stack arguments. */
+ sp -= argc < 8 ? 0 : argc - 8;
+
+ /* Keep the stack aligned. */
+ sp = (uint64_t *) (((uintptr_t) sp) & -16L);
+
+ c_context = (void *) (ucp->uc_mcontext.__reserved
+ + sizeof (struct fpsimd_context));
+
+ c_context->cregs[19] = (uintptr_t) ucp->uc_link;
+ c_context->csp = (uintptr_t) sp;
+ c_context->pcc = (uintptr_t) func;
+ c_context->cregs[29] = (uintptr_t) 0;
+ c_context->cregs[30] = (uintptr_t) &__startcontext;
+
+ va_start (ap, argc);
+ for (i = 0; i < argc; ++i)
+ if (i < 8)
+ c_context->cregs[i] = va_arg (ap, uint64_t);
+ else
+ sp[i - 8] = va_arg (ap, uint64_t);
+
+ va_end (ap);
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
new file mode 100644
index 0000000000..3556d783fc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
@@ -0,0 +1,133 @@
+/* Set current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ .text
+
+ENTRY (__setcontext)
+ /* Save a copy of UCP. */
+ mov c9, c0
+
+ /* Set the signal mask with
+ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */
+ mov x0, #SIG_SETMASK
+ add c1, c9, #UCONTEXT_SIGMASK
+ mov x2, #0
+ mov x3, #_NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbz x0, 1f
+ b C_SYMBOL_NAME (__syscall_error)
+1:
+ /* Restore the capability registers. For Morello, they are saved after the
+ FPSIMD context. */
+ mov c0, c9
+ cfi_def_cfa (c0, 0)
+ cfi_offset (c18, oC0 + 18 * SZCREG)
+ cfi_offset (c19, oC0 + 19 * SZCREG)
+ cfi_offset (c20, oC0 + 20 * SZCREG)
+ cfi_offset (c21, oC0 + 21 * SZCREG)
+ cfi_offset (c22, oC0 + 22 * SZCREG)
+ cfi_offset (c23, oC0 + 23 * SZCREG)
+ cfi_offset (c24, oC0 + 24 * SZCREG)
+ cfi_offset (c25, oC0 + 25 * SZCREG)
+ cfi_offset (c26, oC0 + 26 * SZCREG)
+ cfi_offset (c27, oC0 + 27 * SZCREG)
+ cfi_offset (c28, oC0 + 28 * SZCREG)
+ cfi_offset (c29, oC0 + 29 * SZCREG)
+ cfi_offset (c30, oC0 + 30 * SZCREG)
+
+ cfi_offset ( d8, oV0 + 8 * SZVREG)
+ cfi_offset ( d9, oV0 + 9 * SZVREG)
+ cfi_offset (d10, oV0 + 10 * SZVREG)
+ cfi_offset (d11, oV0 + 11 * SZVREG)
+ cfi_offset (d12, oV0 + 12 * SZVREG)
+ cfi_offset (d13, oV0 + 13 * SZVREG)
+ cfi_offset (d14, oV0 + 14 * SZVREG)
+ cfi_offset (d15, oV0 + 15 * SZVREG)
+
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+ add c10, c9, #oC0
+ ldp c18, c19, [c10, 18 * SZCREG]
+ ldp c20, c21, [c10, 20 * SZCREG]
+ ldp c22, c23, [c10, 22 * SZCREG]
+ ldp c24, c25, [c10, 24 * SZCREG]
+ ldp c26, c27, [c10, 26 * SZCREG]
+ ldp c28, c29, [c10, 28 * SZCREG]
+ ldr c30, [c10, 30 * SZCREG]
+ ldr c2, [c9, oCSP]
+ mov csp, c2
+
+ /* Check for FP SIMD context. We don't support restoring
+ contexts created by the kernel, so this context must have
+ been created by getcontext. Hence we can rely on the
+ first extension block being the FP SIMD context. */
+ add c2, c0, #oEXTENSION
+
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ ldr w1, [c2, #oHEAD + oMAGIC]
+ cmp w1, w3
+ b.ne 2f
+
+ /* Restore the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ ldp q8, q9, [c3], #2 * SZVREG
+ ldp q10, q11, [c3], #2 * SZVREG
+ ldp q12, q13, [c3], #2 * SZVREG
+ ldp q14, q15, [c3], #2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ ldr w4, [c3]
+ msr fpsr, x4
+
+ ldr w4, [c3, oFPCR - oFPSR]
+ msr fpcr, x4
+
+2:
+ ldr c16, [c9, oPCC]
+ /* Restore arg registers. */
+ ldp c2, c3, [c10, 2 * SZCREG]
+ ldp c4, c5, [c10, 4 * SZCREG]
+ ldp c6, c7, [c10, 6 * SZCREG]
+ ldp c0, c1, [c10, 0 * SZCREG]
+ /* Jump to the new pc value. */
+ br c16
+PSEUDO_END (__setcontext)
+weak_alias (__setcontext, setcontext)
+
+ENTRY (__startcontext)
+ mov c0, c19
+ cbnz x0, __setcontext
+1: b HIDDEN_JUMPTARGET (exit)
+END (__startcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
new file mode 100644
index 0000000000..90e4eca413
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
@@ -0,0 +1,120 @@
+/* Modify saved context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ .text
+ENTRY(__swapcontext)
+ /* Set the value returned when swapcontext() returns in this context.
+ And set up x1 to become the return address of the caller, so we
+ can return there with a normal RET instead of an indirect jump. */
+
+ /* For Morello, the capability registers are located in after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ stp czr, c30, [c10, 0 * SZCREG]
+ /* Arrange the oucp context to return to 2f. */
+ adr c30, 2f
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+ str c30, [c9, oPCC]
+ mov c11, csp
+ str c11, [c9, oCSP]
+
+ /* Figure out where to place the fpsimd context extension
+ block. */
+ add c9, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c9, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c9, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c10, c9, #oV0 + 8 * SZVREG
+ stp q8, q9, [c10], #2 * SZVREG
+ stp q10, q11, [c10], #2 * SZVREG
+ stp q12, q13, [c10], #2 * SZVREG
+ stp q14, q15, [c10], #2 * SZVREG
+
+ add c10, c9, #oFPSR
+ mrs x4, fpsr
+ str w4, [c10, #oFPSR - oFPSR]
+ mrs x4, fpcr
+ str w4, [c10, #oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c9, c9, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c9, #oHEAD + oMAGIC]
+ str wzr, [c9, #oHEAD + oSIZE]
+
+ /* Preserve ucp. */
+ mov c11, c1
+
+ /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
+ _NSIG8) */
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ mov c15, c30
+ mov c0, c11
+ bl JUMPTARGET (__setcontext)
+ mov c30, c15
+ RET
+
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+2:
+ /* The oucp context is restored here via an indirect branch,
+ x1 must be restored too which has the real return address. */
+ mov c30, c1
+ RET
+PSEUDO_END (__swapcontext)
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
index fe91db68e8..cd39a2272b 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
@@ -43,6 +43,10 @@ typedef elf_gregset_t gregset_t;
/* Structure to describe FPU registers. */
typedef elf_fpregset_t fpregset_t;
+# ifdef __CHERI_PURE_CAPABILITY__
+/* Structure to describe capability registers. */
+typedef elf_cregset_t cregset_t;
+# endif
#endif
/* Context to describe whole processor state. This only describes
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/user.h b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
index 32fbfd5f1a..e228838bc7 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/user.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
@@ -34,4 +34,14 @@ struct user_fpsimd_struct
unsigned int fpcr;
};
+# ifdef __CHERI_PURE_CAPABILITY__
+struct user_morello_struct
+{
+ __uintcap_t cregs[31];
+ __uintcap_t csp;
+ __uintcap_t rcsp;
+ __uintcap_t pcc;
+};
+# endif
+
#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
index 685d41ca04..429a4c1035 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
@@ -23,6 +23,11 @@
/* Size of an X regiser in bytes. */
#define SZREG 8
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Size of a C register in bytes. */
+# define SZCREG 16
+#endif
+
/* Size of a V register in bytes. */
#define SZVREG 16
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
index ab3930c173..78022326af 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
@@ -18,6 +18,9 @@ RT_SIGFRAME_UCONTEXT rt_sigframe (uc)
RT_SIGFRAME_SIZE sizeof (struct kernel_rt_sigframe)
FPSIMD_CONTEXT_SIZE sizeof (struct fpsimd_context)
+#ifdef __CHERI_PURE_CAPABILITY__
+MORELLO_CONTEXT_SIZE sizeof (struct morello_context)
+#endif
#define ucontext(member) offsetof (ucontext_t, member)
#define stack(member) ucontext (uc_stack.member)
@@ -53,3 +56,15 @@ oMAGIC aarch64_ctx (magic)
oSIZE aarch64_ctx (size)
FPSIMD_MAGIC
+
+#ifdef __CHERI_PURE_CAPABILITY__
+#define morello_context(member) offsetof (struct morello_context, member)
+
+oCHEAD morello_context (head)
+oC0 morello_context (cregs)
+oCSP morello_context (csp)
+oRCSP morello_context (rcsp)
+oPCC morello_context (pcc)
+
+MORELLO_MAGIC
+#endif
^ permalink raw reply [flat|nested] 4+ messages in thread
* [glibc/arm/morello/main] aarch64: morello: add purecap ucontext support
@ 2022-08-05 19:36 Szabolcs Nagy
0 siblings, 0 replies; 4+ messages in thread
From: Szabolcs Nagy @ 2022-08-05 19:36 UTC (permalink / raw)
To: glibc-cvs
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ec5240f821f475379330283349fb9efd569c1ce6
commit ec5240f821f475379330283349fb9efd569c1ce6
Author: Carlos Eduardo Seo <carlos.seo@arm.com>
Date: Thu May 27 17:49:20 2021 -0300
aarch64: morello: add purecap ucontext support
Adjust ucontext layout for purecap ABI and add make/get/set/swapcontext
implementations accordingly.
Note: mcontext layout follows the linux sigcontext struct, in userspace
*context functions rely on the c registers stored in the extension area
and ignore the mcontext fields for x registers.
Diff:
---
sysdeps/unix/sysv/linux/aarch64/bits/procfs.h | 5 +
.../unix/sysv/linux/aarch64/morello/getcontext.S | 121 +++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/makecontext.c | 80 +++++++++++++
.../unix/sysv/linux/aarch64/morello/setcontext.S | 133 +++++++++++++++++++++
.../unix/sysv/linux/aarch64/morello/swapcontext.S | 120 +++++++++++++++++++
sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h | 4 +
sysdeps/unix/sysv/linux/aarch64/sys/user.h | 10 ++
.../unix/sysv/linux/aarch64/ucontext-internal.h | 5 +
sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym | 15 +++
9 files changed, 493 insertions(+)
diff --git a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
index 154fb95e66..596b95e333 100644
--- a/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
+++ b/sysdeps/unix/sysv/linux/aarch64/bits/procfs.h
@@ -33,3 +33,8 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
/* Register set for the floating-point registers. */
typedef struct user_fpsimd_struct elf_fpregset_t;
+
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Register set for the capability registers. */
+typedef struct user_morello_struct elf_cregset_t;
+#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
new file mode 100644
index 0000000000..217ca28285
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/getcontext.S
@@ -0,0 +1,121 @@
+/* Save current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int getcontext (ucontext_t *ucp)
+
+ Returns 0 on success -1 and errno on failure.
+ */
+
+ .text
+
+ENTRY(__getcontext)
+ /* For Morello, we will save only the capability registers. These are saved
+ in a special area in the context extension block after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ /* The saved context will return to the getcontext() call point
+ with a return value of 0 */
+ str czr, [c10, 0 * SZCREG]
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+
+ /* Place LR into the saved PC, this will ensure that when
+ switching to this saved context with setcontext() control
+ will pass back to the caller of getcontext(), we have
+ already arrange to return the appropriate return value in x0
+ above. */
+ str c30, [c9, oPCC]
+
+ /* Save the current CSP */
+ mov c2, csp
+ str c2, [c9, oCSP]
+
+ /* Initialize the pstate. */
+ str xzr, [c0, oPSTATE]
+
+ /* Figure out where to place the first context extension
+ block. */
+ add c2, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c2, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c2, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ stp q8, q9, [c3], # 2 * SZVREG
+ stp q10, q11, [c3], # 2 * SZVREG
+ stp q12, q13, [c3], # 2 * SZVREG
+ stp q14, q15, [c3], # 2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ mrs x4, fpsr
+ str w4, [c3]
+
+ mrs x4, fpcr
+ str w4, [c3, oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c2, c2, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c2, #oHEAD + oMAGIC]
+ str wzr, [c2, #oHEAD + oSIZE]
+
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ /* Return 0 for success */
+ mov x0, 0
+ RET
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+
+ PSEUDO_END (__getcontext)
+weak_alias (__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
new file mode 100644
index 0000000000..3bbfe85887
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/makecontext.c
@@ -0,0 +1,80 @@
+/* Create new context.
+ Copyright (C) 2002-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <string.h>
+#include <ucontext.h>
+#include <asm/sigcontext.h>
+#include "ucontext-internal.h"
+
+/* makecontext sets up a stack and the registers for the
+ user context. The stack looks like this:
+
+ +-----------------------+
+ | padding as required |
+ +-----------------------+
+ sp -> | parameter 7-n |
+ +-----------------------+
+
+ The registers are set up like this:
+ %c0 .. %c7: parameter 1 to 8
+ %c19 : uc_link
+ %csp : stack pointer.
+*/
+
+void
+__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
+{
+ extern void __startcontext (void);
+ uint64_t *sp;
+ va_list ap;
+ int i;
+ struct morello_context *c_context;
+
+ sp = (uint64_t *)
+ ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
+
+ /* Allocate stack arguments. */
+ sp -= argc < 8 ? 0 : argc - 8;
+
+ /* Keep the stack aligned. */
+ sp = (uint64_t *) (((uintptr_t) sp) & -16L);
+
+ c_context = (void *) (ucp->uc_mcontext.__reserved
+ + sizeof (struct fpsimd_context));
+
+ c_context->cregs[19] = (uintptr_t) ucp->uc_link;
+ c_context->csp = (uintptr_t) sp;
+ c_context->pcc = (uintptr_t) func;
+ c_context->cregs[29] = (uintptr_t) 0;
+ c_context->cregs[30] = (uintptr_t) &__startcontext;
+
+ va_start (ap, argc);
+ for (i = 0; i < argc; ++i)
+ if (i < 8)
+ c_context->cregs[i] = va_arg (ap, uint64_t);
+ else
+ sp[i - 8] = va_arg (ap, uint64_t);
+
+ va_end (ap);
+}
+
+weak_alias (__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
new file mode 100644
index 0000000000..3556d783fc
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/setcontext.S
@@ -0,0 +1,133 @@
+/* Set current context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation is intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ .text
+
+ENTRY (__setcontext)
+ /* Save a copy of UCP. */
+ mov c9, c0
+
+ /* Set the signal mask with
+ rt_sigprocmask (SIG_SETMASK, mask, NULL, _NSIG/8). */
+ mov x0, #SIG_SETMASK
+ add c1, c9, #UCONTEXT_SIGMASK
+ mov x2, #0
+ mov x3, #_NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbz x0, 1f
+ b C_SYMBOL_NAME (__syscall_error)
+1:
+ /* Restore the capability registers. For Morello, they are saved after the
+ FPSIMD context. */
+ mov c0, c9
+ cfi_def_cfa (c0, 0)
+ cfi_offset (c18, oC0 + 18 * SZCREG)
+ cfi_offset (c19, oC0 + 19 * SZCREG)
+ cfi_offset (c20, oC0 + 20 * SZCREG)
+ cfi_offset (c21, oC0 + 21 * SZCREG)
+ cfi_offset (c22, oC0 + 22 * SZCREG)
+ cfi_offset (c23, oC0 + 23 * SZCREG)
+ cfi_offset (c24, oC0 + 24 * SZCREG)
+ cfi_offset (c25, oC0 + 25 * SZCREG)
+ cfi_offset (c26, oC0 + 26 * SZCREG)
+ cfi_offset (c27, oC0 + 27 * SZCREG)
+ cfi_offset (c28, oC0 + 28 * SZCREG)
+ cfi_offset (c29, oC0 + 29 * SZCREG)
+ cfi_offset (c30, oC0 + 30 * SZCREG)
+
+ cfi_offset ( d8, oV0 + 8 * SZVREG)
+ cfi_offset ( d9, oV0 + 9 * SZVREG)
+ cfi_offset (d10, oV0 + 10 * SZVREG)
+ cfi_offset (d11, oV0 + 11 * SZVREG)
+ cfi_offset (d12, oV0 + 12 * SZVREG)
+ cfi_offset (d13, oV0 + 13 * SZVREG)
+ cfi_offset (d14, oV0 + 14 * SZVREG)
+ cfi_offset (d15, oV0 + 15 * SZVREG)
+
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+ add c10, c9, #oC0
+ ldp c18, c19, [c10, 18 * SZCREG]
+ ldp c20, c21, [c10, 20 * SZCREG]
+ ldp c22, c23, [c10, 22 * SZCREG]
+ ldp c24, c25, [c10, 24 * SZCREG]
+ ldp c26, c27, [c10, 26 * SZCREG]
+ ldp c28, c29, [c10, 28 * SZCREG]
+ ldr c30, [c10, 30 * SZCREG]
+ ldr c2, [c9, oCSP]
+ mov csp, c2
+
+ /* Check for FP SIMD context. We don't support restoring
+ contexts created by the kernel, so this context must have
+ been created by getcontext. Hence we can rely on the
+ first extension block being the FP SIMD context. */
+ add c2, c0, #oEXTENSION
+
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ ldr w1, [c2, #oHEAD + oMAGIC]
+ cmp w1, w3
+ b.ne 2f
+
+ /* Restore the FP SIMD context. */
+ add c3, c2, #oV0 + 8 * SZVREG
+ ldp q8, q9, [c3], #2 * SZVREG
+ ldp q10, q11, [c3], #2 * SZVREG
+ ldp q12, q13, [c3], #2 * SZVREG
+ ldp q14, q15, [c3], #2 * SZVREG
+
+ add c3, c2, oFPSR
+
+ ldr w4, [c3]
+ msr fpsr, x4
+
+ ldr w4, [c3, oFPCR - oFPSR]
+ msr fpcr, x4
+
+2:
+ ldr c16, [c9, oPCC]
+ /* Restore arg registers. */
+ ldp c2, c3, [c10, 2 * SZCREG]
+ ldp c4, c5, [c10, 4 * SZCREG]
+ ldp c6, c7, [c10, 6 * SZCREG]
+ ldp c0, c1, [c10, 0 * SZCREG]
+ /* Jump to the new pc value. */
+ br c16
+PSEUDO_END (__setcontext)
+weak_alias (__setcontext, setcontext)
+
+ENTRY (__startcontext)
+ mov c0, c19
+ cbnz x0, __setcontext
+1: b HIDDEN_JUMPTARGET (exit)
+END (__startcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
new file mode 100644
index 0000000000..90e4eca413
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/swapcontext.S
@@ -0,0 +1,120 @@
+/* Modify saved context.
+
+ Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#include "ucontext_i.h"
+#include "ucontext-internal.h"
+
+/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */
+
+ .text
+ENTRY(__swapcontext)
+ /* Set the value returned when swapcontext() returns in this context.
+ And set up x1 to become the return address of the caller, so we
+ can return there with a normal RET instead of an indirect jump. */
+
+ /* For Morello, the capability registers are located in after the FPSIMD
+ context. */
+ add c9, c0, #oEXTENSION + FPSIMD_CONTEXT_SIZE
+
+ /* Write the context extension morello header. */
+ mov w3, #(MORELLO_MAGIC & 0xffff)
+ movk w3, #(MORELLO_MAGIC >> 16), lsl #16
+ str w3, [c9, #oCHEAD + oMAGIC]
+ mov w3, #MORELLO_CONTEXT_SIZE
+ str w3, [c9, #oCHEAD + oSIZE]
+
+ add c10, c9, #oC0
+ stp czr, c30, [c10, 0 * SZCREG]
+ /* Arrange the oucp context to return to 2f. */
+ adr c30, 2f
+
+ stp c18, c19, [c10, 18 * SZCREG]
+ stp c20, c21, [c10, 20 * SZCREG]
+ stp c22, c23, [c10, 22 * SZCREG]
+ stp c24, c25, [c10, 24 * SZCREG]
+ stp c26, c27, [c10, 26 * SZCREG]
+ stp c28, c29, [c10, 28 * SZCREG]
+ str c30, [c10, 30 * SZCREG]
+ str c30, [c9, oPCC]
+ mov c11, csp
+ str c11, [c9, oCSP]
+
+ /* Figure out where to place the fpsimd context extension
+ block. */
+ add c9, c0, #oEXTENSION
+
+ /* Write the context extension fpsimd header. */
+ mov w3, #(FPSIMD_MAGIC & 0xffff)
+ movk w3, #(FPSIMD_MAGIC >> 16), lsl #16
+ str w3, [c9, #oHEAD + oMAGIC]
+ mov w3, #FPSIMD_CONTEXT_SIZE
+ str w3, [c9, #oHEAD + oSIZE]
+
+ /* Fill in the FP SIMD context. */
+ add c10, c9, #oV0 + 8 * SZVREG
+ stp q8, q9, [c10], #2 * SZVREG
+ stp q10, q11, [c10], #2 * SZVREG
+ stp q12, q13, [c10], #2 * SZVREG
+ stp q14, q15, [c10], #2 * SZVREG
+
+ add c10, c9, #oFPSR
+ mrs x4, fpsr
+ str w4, [c10, #oFPSR - oFPSR]
+ mrs x4, fpcr
+ str w4, [c10, #oFPCR - oFPSR]
+
+ /* Write the termination context extension header after the Morello
+ context. */
+ add c9, c9, #FPSIMD_CONTEXT_SIZE + MORELLO_CONTEXT_SIZE
+ str wzr, [c9, #oHEAD + oMAGIC]
+ str wzr, [c9, #oHEAD + oSIZE]
+
+ /* Preserve ucp. */
+ mov c11, c1
+
+ /* rt_sigprocmask (SIG_SETMASK, &ucp->uc_sigmask, &oucp->uc_sigmask,
+ _NSIG8) */
+ /* Grab the signal mask */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG8) */
+ add c2, c0, #UCONTEXT_SIGMASK
+ mov x0, SIG_BLOCK
+ mov x1, 0
+ mov x3, _NSIG8
+ mov x8, SYS_ify (rt_sigprocmask)
+ svc 0
+ cbnz x0, 1f
+
+ mov c15, c30
+ mov c0, c11
+ bl JUMPTARGET (__setcontext)
+ mov c30, c15
+ RET
+
+1:
+ b C_SYMBOL_NAME(__syscall_error)
+2:
+ /* The oucp context is restored here via an indirect branch,
+ x1 must be restored too which has the real return address. */
+ mov c30, c1
+ RET
+PSEUDO_END (__swapcontext)
+weak_alias (__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
index fe91db68e8..cd39a2272b 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
@@ -43,6 +43,10 @@ typedef elf_gregset_t gregset_t;
/* Structure to describe FPU registers. */
typedef elf_fpregset_t fpregset_t;
+# ifdef __CHERI_PURE_CAPABILITY__
+/* Structure to describe capability registers. */
+typedef elf_cregset_t cregset_t;
+# endif
#endif
/* Context to describe whole processor state. This only describes
diff --git a/sysdeps/unix/sysv/linux/aarch64/sys/user.h b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
index 32fbfd5f1a..e228838bc7 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sys/user.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sys/user.h
@@ -34,4 +34,14 @@ struct user_fpsimd_struct
unsigned int fpcr;
};
+# ifdef __CHERI_PURE_CAPABILITY__
+struct user_morello_struct
+{
+ __uintcap_t cregs[31];
+ __uintcap_t csp;
+ __uintcap_t rcsp;
+ __uintcap_t pcc;
+};
+# endif
+
#endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
index 685d41ca04..429a4c1035 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext-internal.h
@@ -23,6 +23,11 @@
/* Size of an X regiser in bytes. */
#define SZREG 8
+#ifdef __CHERI_PURE_CAPABILITY__
+/* Size of a C register in bytes. */
+# define SZCREG 16
+#endif
+
/* Size of a V register in bytes. */
#define SZVREG 16
diff --git a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
index ab3930c173..78022326af 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/aarch64/ucontext_i.sym
@@ -18,6 +18,9 @@ RT_SIGFRAME_UCONTEXT rt_sigframe (uc)
RT_SIGFRAME_SIZE sizeof (struct kernel_rt_sigframe)
FPSIMD_CONTEXT_SIZE sizeof (struct fpsimd_context)
+#ifdef __CHERI_PURE_CAPABILITY__
+MORELLO_CONTEXT_SIZE sizeof (struct morello_context)
+#endif
#define ucontext(member) offsetof (ucontext_t, member)
#define stack(member) ucontext (uc_stack.member)
@@ -53,3 +56,15 @@ oMAGIC aarch64_ctx (magic)
oSIZE aarch64_ctx (size)
FPSIMD_MAGIC
+
+#ifdef __CHERI_PURE_CAPABILITY__
+#define morello_context(member) offsetof (struct morello_context, member)
+
+oCHEAD morello_context (head)
+oC0 morello_context (cregs)
+oCSP morello_context (csp)
+oRCSP morello_context (rcsp)
+oPCC morello_context (pcc)
+
+MORELLO_MAGIC
+#endif
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-11-23 14:47 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-27 13:57 [glibc/arm/morello/main] aarch64: morello: add purecap ucontext support Szabolcs Nagy
-- strict thread matches above, loose matches on Subject: below --
2022-11-23 14:47 Szabolcs Nagy
2022-10-26 15:18 Szabolcs Nagy
2022-08-05 19:36 Szabolcs Nagy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).