[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