]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
aarch64: morello: add purecap syscall support
authorCarlos Eduardo Seo <carlos.seo@arm.com>
Thu, 8 Apr 2021 15:49:27 +0000 (12:49 -0300)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Thu, 27 Oct 2022 13:46:50 +0000 (14:46 +0100)
Support the Morello Linux purecap syscall ABI.  The macro definitions
are moved to a morello specific sysdep.h to avoid cluttering the
aarch64 one.

sysdeps/unix/sysv/linux/aarch64/clone.S
sysdeps/unix/sysv/linux/aarch64/ioctl.S
sysdeps/unix/sysv/linux/aarch64/morello/sysdep.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/aarch64/syscall.S

index ad80ac829cf0474f941ee4fbae775f80bf96311f..4d7852304bd2a64f7a00ba397465d6bbed8a47e9 100644 (file)
 #define _ERRNO_H       1
 #include <bits/errno.h>
 
-/* int clone(int (*fn)(void *arg),            x0
-            void *child_stack,               x1
-            int flags,                       x2
-            void *arg,                       x3
-            pid_t *ptid,                     x4
-            struct user_desc *tls,           x5
-             pid_t *ctid);                    x6
+#ifdef __CHERI_PURE_CAPABILITY__
+# define arg0  c0
+# define arg1  c1
+# define arg2  c2
+# define arg3  c3
+# define arg4  c4
+# define arg5  c5
+# define arg6  c6
+# define tmp0  c10
+# define tmp1  c11
+# define tmp2  c12
+#else
+# define arg0  x0
+# define arg1  x1
+# define arg2  x2
+# define arg3  x3
+# define arg4  x4
+# define arg5  x5
+# define arg6  x6
+# define tmp0  x10
+# define tmp1  x11
+# define tmp2  x12
+#endif
+
+/* int clone(int (*fn)(void *arg),            arg0
+            void *child_stack,               arg1
+            int flags,                       arg2
+            void *arg,                       arg3
+            pid_t *ptid,                     arg4
+            struct user_desc *tls,           arg5
+             pid_t *ctid);                    arg6
  */
         .text
 ENTRY(__clone)
+#ifndef __CHERI_PURE_CAPABILITY__
        PTR_ARG (0)
        PTR_ARG (1)
        PTR_ARG (3)
        PTR_ARG (4)
        PTR_ARG (5)
        PTR_ARG (6)
+#else
+       cbz     x9, L(skip_args)
+       gclen   x10, c9
+       ldr     c4, [c9]
+       cmp     x10, 16
+       bls     L(skip_args)
+       ldr     c5, [c9,16]
+       cmp     x10, 32
+       bls     L(skip_args)
+       ldr     c6, [c9,32]
+L(skip_args):
+#endif
        /* Save args for the child.  */
-       mov     x10, x0
-       mov     x11, x2
-       mov     x12, x3
+       mov     tmp0, arg0
+       mov     tmp1, arg2
+       mov     tmp2, arg3
 
        /* Sanity check args.  */
        mov     x0, #-EINVAL
        cbz     x10, .Lsyscall_error
        /* Align sp.  */
+#ifndef __CHERI_PURE_CAPABILITY__
        and     x1, x1, -16
+#else
+       alignd  c1, c1, 4
+#endif
        cbz     x1, .Lsyscall_error
 
        /* Do the system call.  */
        /* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
-       mov     x0, x2                  /* flags  */
+       mov     arg0, arg2                  /* flags  */
        /* New sp is already in x1.  */
-       mov     x2, x4                  /* ptid  */
-       mov     x3, x5                  /* tls  */
-       mov     x4, x6                  /* ctid  */
+       mov     arg2, arg4                      /* ptid  */
+       mov     arg3, arg5                      /* tls  */
+       mov     arg4, arg6                      /* ctid  */
        mov     x8, #SYS_ify(clone)
        svc     0x0
 
@@ -75,8 +116,8 @@ thread_start:
        mov     x29, 0
 
        /* Pick the function arg and execute.  */
-       mov     x0, x12
-       blr     x10
+       mov     arg0, tmp2
+       blr     tmp0
 
        /* We are done, pass the return value through x0.  */
        mov     x8, #SYS_ify(exit)
index eb2f7211d74af1497440a4c0aacf09e0313abe26..88c814345240dffb620aff6466578a329c3f0851 100644 (file)
 ENTRY(__ioctl)
        mov     x8, #__NR_ioctl
        sxtw    x0, w0
+#ifdef __CHERI_PURE_CAPABILITY__
+       cbz     x9, L(skip_arg3)
+       ldr     c2, [c9]
+L(skip_arg3):
+#endif
        svc     #0x0
        cmn     x0, #4095
        b.cs    .Lsyscall_error
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/morello/sysdep.h
new file mode 100644 (file)
index 0000000..5db89b0
--- /dev/null
@@ -0,0 +1,116 @@
+/* Copyright (C) 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/>.  */
+
+#ifndef _LINUX_AARCH64_MORELLO_SYSDEP_H
+#define _LINUX_AARCH64_MORELLO_SYSDEP_H 1
+
+#include <sysdeps/unix/sysv/linux/aarch64/sysdep.h>
+
+#ifdef __ASSEMBLER__
+# if !IS_IN (libc)
+#  undef SYSCALL_ERROR_HANDLER
+#  if RTLD_PRIVATE_ERRNO
+#   define SYSCALL_ERROR_HANDLER                               \
+.Lsyscall_error:                                               \
+       neg     w0, w0;                                         \
+       adrp    c1, :got:rtld_errno;                            \
+       ldr     c1, [c1, :got_lo12:rtld_errno];                 \
+       str     w0, [c1];                                       \
+       mov     x0, -1;                                         \
+       RET;
+#  else
+#   define SYSCALL_ERROR_HANDLER                               \
+.Lsyscall_error:                                               \
+       neg     w4, w0;                                         \
+       adrp    c1, :gottprel:errno;                            \
+       add     c1, c1, :gottprel_lo12:errno;                   \
+       ldp     x1, x2, [c1];                                   \
+       mrs     c3, ctpidr_el0;                                 \
+       add     c1, c3, x1, uxtx;                               \
+       scbnds  c1, c1, x2;                                     \
+       mov     x0, -1;                                         \
+       str     w4, [c1];                                       \
+       RET;
+#  endif
+# endif
+
+#else /* not __ASSEMBLER__ */
+
+typedef __intcap_t __sysarg_t;
+
+# undef INTERNAL_SYSCALL_RAW
+# define INTERNAL_SYSCALL_RAW(name, nr, args...)               \
+  ({ __sysarg_t _sys_result;                                           \
+     {                                                         \
+       LOAD_ARGS_##nr (args)                                   \
+       register long _x8 asm ("x8") = (name);                  \
+       asm volatile ("svc      0       // syscall " # name     \
+                    : "=r" (_x0) : "r"(_x8) ASM_ARGS_##nr : "memory"); \
+       _sys_result = _x0;                                      \
+     }                                                         \
+     _sys_result; })
+
+# undef LOAD_ARGS_0
+# undef LOAD_ARGS_1
+# undef LOAD_ARGS_2
+# undef LOAD_ARGS_3
+# undef LOAD_ARGS_4
+# undef LOAD_ARGS_5
+# undef LOAD_ARGS_6
+# undef LOAD_ARGS_7
+
+# define LOAD_ARGS_0()                         \
+  register __sysarg_t _x0 asm ("c0");
+# define LOAD_ARGS_1(c0)                       \
+  __sysarg_t _x0tmp = (__sysarg_t) (c0);       \
+  LOAD_ARGS_0 ()                               \
+  _x0 = _x0tmp;
+# define LOAD_ARGS_2(c0, c1)                   \
+  __sysarg_t _x1tmp = (__sysarg_t) (c1);       \
+  LOAD_ARGS_1 (c0)                             \
+  register __sysarg_t _x1 asm ("c1") = _x1tmp;
+# define LOAD_ARGS_3(c0, c1, c2)               \
+  __sysarg_t _x2tmp = (__sysarg_t) (c2);       \
+  LOAD_ARGS_2 (c0, c1)                         \
+  register __sysarg_t _x2 asm ("c2") = _x2tmp;
+# define LOAD_ARGS_4(c0, c1, c2, c3)           \
+  __sysarg_t _x3tmp = (__sysarg_t) (c3);       \
+  LOAD_ARGS_3 (c0, c1, c2)                     \
+  register __sysarg_t _x3 asm ("c3") = _x3tmp;
+# define LOAD_ARGS_5(c0, c1, c2, c3, c4)       \
+  __sysarg_t _x4tmp = (__sysarg_t) (c4);       \
+  LOAD_ARGS_4 (c0, c1, c2, c3)                 \
+  register __sysarg_t _x4 asm ("c4") = _x4tmp;
+# define LOAD_ARGS_6(c0, c1, c2, c3, c4, c5)   \
+  __sysarg_t _x5tmp = (__sysarg_t) (c5);       \
+  LOAD_ARGS_5 (c0, c1, c2, c3, c4)             \
+  register __sysarg_t _x5 asm ("c5") = _x5tmp;
+# define LOAD_ARGS_7(c0, c1, c2, c3, c4, c5, c6)\
+  __sysarg_t _x6tmp = (__sysarg_t) (x6);       \
+  LOAD_ARGS_6 (c0, c1, c2, c3, c4, c5)         \
+  register __sysarg_t _x6 asm ("c6") = _x6tmp;
+
+#endif /* __ASSEMBLER__ */
+
+/* Disable pointer mangling for purecap ABI.  */
+#undef PTR_MANGLE
+#undef PTR_MANGLE2
+#undef PTR_DEMANGLE
+#undef PTR_DEMANGLE2
+
+#endif /* linux/aarch64/morello/sysdep.h */
index 9ddecb21c3cb0fac856eb8ecad0a6ac1ffd35132..43a81fc248264cb75fb14bf3661aba8839f87541 100644 (file)
 
 ENTRY (syscall)
        uxtw    x8, w0
+#ifdef __CHERI_PURE_CAPABILITY__
+       cbz     x9, L(skip_args)
+       gclen   x10, c9
+       ldr     c0, [c9]
+       cmp     x10, 16
+       bls     L(skip_args)
+       ldr     c1, [c9,16]
+       cmp     x10, 32
+       bls     L(skip_args)
+       ldr     c2, [c9,32]
+       cmp     x10, 48
+       bls     L(skip_args)
+       ldr     c3, [c9,48]
+       cmp     x10, 64
+       bls     L(skip_args)
+       ldr     c4, [c9,64]
+       cmp     x10, 80
+       bls     L(skip_args)
+       ldr     c5, [c9,80]
+       cmp     x10, 96
+       bls     L(skip_args)
+       ldr     c6, [c9,96]
+L(skip_args):
+#else
        mov     x0, x1
        mov     x1, x2
        mov     x2, x3
@@ -35,6 +59,7 @@ ENTRY (syscall)
        mov     x4, x5
        mov     x5, x6
        mov     x6, x7
+#endif
        svc     0x0
        cmn     x0, #4095
        b.cs    1f