diff options
| -rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/clone.S | 3 | ||||
| -rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/clone3.S | 3 | ||||
| -rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/sysdep.h | 25 | ||||
| -rw-r--r-- | sysdeps/unix/sysv/linux/aarch64/vfork.S | 3 |
4 files changed, 34 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S index 97e1afa57f..bab0ce7719 100644 --- a/sysdeps/unix/sysv/linux/aarch64/clone.S +++ b/sysdeps/unix/sysv/linux/aarch64/clone.S @@ -51,6 +51,9 @@ ENTRY(__clone) and x1, x1, -16 cbz x1, .Lsyscall_error + /* Clear ZA state of SME. */ + CALL_LIBC_ARM_ZA_DISABLE + /* Do the system call. */ /* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid. */ mov x0, x2 /* flags */ diff --git a/sysdeps/unix/sysv/linux/aarch64/clone3.S b/sysdeps/unix/sysv/linux/aarch64/clone3.S index 443e117bf9..f1f22c9865 100644 --- a/sysdeps/unix/sysv/linux/aarch64/clone3.S +++ b/sysdeps/unix/sysv/linux/aarch64/clone3.S @@ -50,6 +50,9 @@ ENTRY(__clone3) cbz x10, .Lsyscall_error /* No NULL cl_args pointer. */ cbz x2, .Lsyscall_error /* No NULL function pointer. */ + /* Clear ZA state of SME. */ + CALL_LIBC_ARM_ZA_DISABLE + /* Do the system call, the kernel expects: x8: system call number x0: cl_args diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h index 39b602900f..b220c6febd 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h +++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h @@ -247,6 +247,31 @@ #undef HAVE_INTERNAL_BRK_ADDR_SYMBOL #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 +/* Clear ZA state of SME (C version). */ +/* The __libc_arm_za_disable function has special calling convention + that allows to call it without stack manipulation and preserving + most of the registers. */ +#define CALL_LIBC_ARM_ZA_DISABLE() \ +({ \ + unsigned long int __tmp; \ + asm volatile ( \ + " mov %0, x30\n" \ + " .cfi_register x30, %0\n" \ + " bl __libc_arm_za_disable\n" \ + " mov x30, %0\n" \ + " .cfi_register %0, x30\n" \ + : "=r" (__tmp) \ + : \ + : "x14", "x15", "x16", "x17", "x18", "memory" ); \ +}) + +/* Do clear ZA state of SME before making normal clone syscall. */ +#define INLINE_CLONE_SYSCALL(a0, a1, a2, a3, a4) \ +({ \ + CALL_LIBC_ARM_ZA_DISABLE (); \ + INLINE_SYSCALL_CALL (clone, a0, a1, a2, a3, a4); \ +}) + #endif /* __ASSEMBLER__ */ #endif /* linux/aarch64/sysdep.h */ diff --git a/sysdeps/unix/sysv/linux/aarch64/vfork.S b/sysdeps/unix/sysv/linux/aarch64/vfork.S index d5943a7485..2600bc9be3 100644 --- a/sysdeps/unix/sysv/linux/aarch64/vfork.S +++ b/sysdeps/unix/sysv/linux/aarch64/vfork.S @@ -27,6 +27,9 @@ ENTRY (__vfork) + /* Clear ZA state of SME. */ + CALL_LIBC_ARM_ZA_DISABLE + mov x0, #0x4111 /* CLONE_VM | CLONE_VFORK | SIGCHLD */ mov x1, sp DO_CALL (clone, 2) |
