[PATCH v6 1/3] aarch64: define macro for calling __libc_arm_za_disable

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Tue Oct 7 13:16:55 GMT 2025



On 06/10/25 08:53, Yury Khrustalev wrote:
> Common sequence of instructions is used in several places in
> assembly files, so define it in one place as a preprocessor
> macro.
> ---
>  sysdeps/aarch64/__longjmp.S                  | 12 ++----------
>  sysdeps/aarch64/setjmp.S                     | 12 ++----------
>  sysdeps/unix/sysv/linux/aarch64/setcontext.S | 10 +---------
>  sysdeps/unix/sysv/linux/aarch64/sysdep.h     | 11 +++++++++++
>  4 files changed, 16 insertions(+), 29 deletions(-)
> 
> diff --git a/sysdeps/aarch64/__longjmp.S b/sysdeps/aarch64/__longjmp.S
> index 70ac02c44b..53b42e1bdc 100644
> --- a/sysdeps/aarch64/__longjmp.S
> +++ b/sysdeps/aarch64/__longjmp.S
> @@ -26,16 +26,8 @@
>  ENTRY (__longjmp)
>  
>  #if IS_IN(libc)
> -	/* Disable ZA state of SME in libc.a and libc.so, but not in ld.so.
> -	   The calling convention of __libc_arm_za_disable allows to do
> -	   this thus allowing to avoid saving to and reading from stack.
> -	   As a result we also don't need to sign the return address and
> -	   check it after returning because it is not stored to stack.  */
> -	mov	x13, x30
> -	cfi_register (x30, x13)
> -	bl	__libc_arm_za_disable
> -	mov	x30, x13
> -	cfi_register (x13, x30)
> +	/* Disable ZA state of SME in libc.a and libc.so, but not in ld.so.  */
> +	CALL_LIBC_ARM_ZA_DISABLE
>  #endif
>  
>  	cfi_def_cfa (x0, 0)
> diff --git a/sysdeps/aarch64/setjmp.S b/sysdeps/aarch64/setjmp.S
> index 53c5e7d8cc..92cedfad83 100644
> --- a/sysdeps/aarch64/setjmp.S
> +++ b/sysdeps/aarch64/setjmp.S
> @@ -37,16 +37,8 @@ ENTRY_ALIGN (__sigsetjmp, 2)
>  1:
>  
>  #if IS_IN(libc)
> -	/* Disable ZA state of SME in libc.a and libc.so, but not in ld.so.
> -	   The calling convention of __libc_arm_za_disable allows to do
> -	   this thus allowing to avoid saving to and reading from stack.
> -	   As a result we also don't need to sign the return address and
> -	   check it after returning because it is not stored to stack.  */
> -	mov	x13, x30
> -	cfi_register (x30, x13)
> -	bl	__libc_arm_za_disable
> -	mov	x30, x13
> -	cfi_register (x13, x30)
> +	/* Disable ZA state of SME in libc.a and libc.so, but not in ld.so.  */
> +	CALL_LIBC_ARM_ZA_DISABLE
>  #endif
>  
>  	stp	x19, x20, [x0, #JB_X19<<3]
> diff --git a/sysdeps/unix/sysv/linux/aarch64/setcontext.S b/sysdeps/unix/sysv/linux/aarch64/setcontext.S
> index d9716f012e..8e98594663 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/setcontext.S
> +++ b/sysdeps/unix/sysv/linux/aarch64/setcontext.S
> @@ -49,15 +49,7 @@ ENTRY (__setcontext)
>  	b	C_SYMBOL_NAME (__syscall_error)
>  1:
>  	/* Clear ZA state of SME.  */
> -	/* The calling convention of __libc_arm_za_disable allows to do
> -	   this thus allowing to avoid saving to and reading from stack.
> -	   As a result we also don't need to sign the return address and
> -	   check it after returning because it is not stored to stack.  */
> -	mov	x13, x30
> -	cfi_register (x30, x13)
> -	bl	__libc_arm_za_disable
> -	mov	x30, x13
> -	cfi_register (x13, x30)
> +	CALL_LIBC_ARM_ZA_DISABLE
>  	/* Restore the general purpose registers.  */
>  	mov	x0, x9
>  	cfi_def_cfa (x0, 0)
> diff --git a/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
> index f0e8d64eef..5971e58def 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/sysdep.h
> +++ b/sysdeps/unix/sysv/linux/aarch64/sysdep.h
> @@ -150,6 +150,17 @@
>      mov x8, SYS_ify (syscall_name);		\
>      svc 0
>  
> +/* Clear ZA state of SME (ASM 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		\
> +    mov			x13, x30;		\
> +    .cfi_register	x30, x13;		\
> +    bl			__libc_arm_za_disable;	\
> +    mov			x30, x13;		\
> +    .cfi_register	x13, x30;
> +
>  #else /* not __ASSEMBLER__ */

I think it would be better to be a proper gas macro instead of a C
macro, even if the sequence does not use internal labels or control
flow:

        .macro CALL_LIBC_ARM_ZA_DISABLE
        mov             x13, x30
        .cfi_register   x30, x13
        bl              __libc_arm_za_disable
        mov             x30, x13
        .cfi_register   x13, x30
        .endm

It is a slight clear syntax, do not pollute the global namespace, and
have better error messages. 

>  
>  # define VDSO_NAME  "LINUX_2.6.39"



More information about the Libc-alpha mailing list