summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/clone.S3
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/clone3.S3
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/sysdep.h25
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/vfork.S3
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)