[PATCH] aarch64: simplify __libc_arm_za_disable failure path

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Wed Apr 22 17:34:40 GMT 2026



On 21/04/26 10:08, Muhammad Kamran wrote:
> The failure tail of __libc_arm_za_disable only leads to
> __libc_fatal, so it does not need to preserve call frame state.
> 
> Remove the PAC prologue, frame setup, saved cntd value, stack
> stores, and associated CFI directives from the fatal path, leaving
> only the required SME state shutdown and fatal call.
> 
> Add tst-sme-za-disable-fail to exercise the abort path by providing
> a TPIDR2 block with non-zero reserved bytes and checking that the
> process terminates with SIGABRT and the expected fatal message.
> ---
>  sysdeps/aarch64/Makefile                  |  2 +
>  sysdeps/aarch64/__arm_za_disable.S        | 10 ----
>  sysdeps/aarch64/tst-sme-helper.h          | 12 ++--
>  sysdeps/aarch64/tst-sme-za-disable-fail.c | 67 +++++++++++++++++++++++
>  4 files changed, 75 insertions(+), 16 deletions(-)
>  create mode 100644 sysdeps/aarch64/tst-sme-za-disable-fail.c
> 
> diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
> index d6c5cc96ca..57132179fd 100644
> --- a/sysdeps/aarch64/Makefile
> +++ b/sysdeps/aarch64/Makefile
> @@ -82,9 +82,11 @@ tests-internal += \
>    tst-sme-clone3 \
>    tst-sme-fork \
>    tst-sme-vfork \
> +  tst-sme-za-disable-fail \
>    # tests-internal
>  
>  $(objpfx)tst-sme-clone3: $(objpfx)clone3.o $(objpfx)__arm_za_disable.o
> +$(objpfx)tst-sme-za-disable-fail: $(objpfx)__arm_za_disable.o
>  endif
>  
>  ifeq ($(subdir),malloc)
> diff --git a/sysdeps/aarch64/__arm_za_disable.S b/sysdeps/aarch64/__arm_za_disable.S
> index c9663e3bcb..f360c8c77b 100644
> --- a/sysdeps/aarch64/__arm_za_disable.S
> +++ b/sysdeps/aarch64/__arm_za_disable.S
> @@ -88,16 +88,6 @@ L(save_loop):
>  L(end):
>  	ret
>  L(fail):
> -	paciasp
> -	cfi_negate_ra_state
> -	stp	x29, x30, [sp, -32]!
> -	cfi_adjust_cfa_offset (32)
> -	cfi_rel_offset (x29, 0)
> -	cfi_rel_offset (x30, 8)
> -	mov	x29, sp
> -	.inst	0x04e0e3f0  /* cntd	x16  */
> -	str	x16, [sp, 16]
> -	cfi_rel_offset (46, 16)
>  	.inst	0xd503467f  /* smstop  */
>  	adrp	x0, L(msg)
>  	add	x0, x0, :lo12:L(msg)
> diff --git a/sysdeps/aarch64/tst-sme-helper.h b/sysdeps/aarch64/tst-sme-helper.h
> index 2ae2cc2f47..66e016f0b8 100644
> --- a/sysdeps/aarch64/tst-sme-helper.h
> +++ b/sysdeps/aarch64/tst-sme-helper.h
> @@ -23,7 +23,7 @@ struct blk {
>  };
>  
>  /* Read SVCR to get SM (bit0) and ZA (bit1) state.  */
> -static unsigned long
> +static unsigned long __attribute__ ((unused))

Use __attribute_maybe_unused__ or defined it as inline.

>  get_svcr (void)
>  {
>    register unsigned long x0 asm ("x0");
> @@ -34,7 +34,7 @@ get_svcr (void)
>  }
>  
>  /* Returns tpidr2.  */
> -static void *
> +static __attribute__ ((unused)) void *
>  get_tpidr2 (void)
>  {
>    register unsigned long x0 asm ("x0");
> @@ -45,7 +45,7 @@ get_tpidr2 (void)
>  }
>  
>  /* Obtains current streaming SVE vector register size.  */
> -static unsigned long
> +static unsigned long __attribute__ ((unused))
>  get_svl (void)
>  {
>    register unsigned long x0 asm ("x0");
> @@ -56,7 +56,7 @@ get_svl (void)
>  }
>  
>  /* PSTATE.ZA = 1, set ZA state to active.  */
> -static void
> +static void __attribute__ ((unused))
>  start_za (void)
>  {
>    asm volatile (
> @@ -64,7 +64,7 @@ start_za (void)
>  }
>  
>  /* Load data into ZA byte by byte from p.  */
> -static void __attribute__ ((noinline))
> +static void __attribute__ ((noinline, unused))
>  load_za (const void *buf, unsigned long svl)
>  {
>    register unsigned long x15 asm ("x15") = 0;
> @@ -84,7 +84,7 @@ load_za (const void *buf, unsigned long svl)
>  }
>  
>  /* Set tpidr2 to BLK.  */
> -static void
> +static void __attribute__ ((unused))
>  set_tpidr2 (struct blk *blk)
>  {
>    register unsigned long x0 asm ("x0") = (unsigned long)blk;
> diff --git a/sysdeps/aarch64/tst-sme-za-disable-fail.c b/sysdeps/aarch64/tst-sme-za-disable-fail.c
> new file mode 100644
> index 0000000000..d3a6bebaf9
> --- /dev/null
> +++ b/sysdeps/aarch64/tst-sme-za-disable-fail.c
> @@ -0,0 +1,67 @@
> +/* Test that __libc_arm_za_disable aborts on unknown TPIDR2 extensions.
> +   Copyright (C) 2026 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 <signal.h>
> +#include <stdint.h>
> +#include <sys/auxv.h>
> +
> +#include <support/capture_subprocess.h>
> +#include <support/check.h>
> +#include <support/test-driver.h>
> +
> +#include "tst-sme-helper.h"
> +
> +extern void __libc_arm_za_disable (void);
> +
> +/* Required by __arm_za_disable.o and provided by the startup code
> +   as a hidden symbol.  */
> +uint64_t _dl_hwcap2;
> +
> +static struct blk blk = {
> +  .za_save_buffer = NULL,
> +  .num_za_save_slices = 0,
> +  .__reserved = { 1, 0, 0, 0, 0, 0 },
> +};
> +
> +static void
> +do_abort (void *closure)
> +{
> +  start_za ();
> +  set_tpidr2 (closure);
> +  __libc_arm_za_disable ();
> +}
> +
> +static int
> +do_test (void)
> +{
> +  _dl_hwcap2 = getauxval (AT_HWCAP2);
> +  if ((_dl_hwcap2 & HWCAP2_SME) == 0)
> +    FAIL_UNSUPPORTED ("kernel or CPU does not support SME");
> +
> +  struct support_capture_subprocess result
> +      = support_capture_subprocess (do_abort, &blk);
> +  support_capture_subprocess_check (&result, "tst-sme-za-disable-fail",
> +				    -SIGABRT, sc_allow_stderr);
> +  TEST_COMPARE_STRING (result.err.buffer,
> +		       "FATAL: __libc_arm_za_disable failed.\n");
> +  support_capture_subprocess_free (&result);
> +
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>



More information about the Libc-alpha mailing list