[glibc] AArch64: simplify __libc_arm_za_disable failure path
Wilco Dijkstra via Glibc-cvs <[email protected]> Mon, 18 May 2026 14:11:10 +0000 (GMT)
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d093102297b8ba326b946b544f52af31ba6d1135 commit d093102297b8ba326b946b544f52af31ba6d1135 Author: Muhammad Kamran <[email protected]> Date: Mon May 18 14:03:02 2026 +0000 AArch64: simplify __libc_arm_za_disable failure path 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. Diff: --- sysdeps/aarch64/Makefile | 2 + sysdeps/aarch64/__arm_za_disable.S | 12 +----- sysdeps/aarch64/tst-sme-helper.h | 12 +++--- sysdeps/aarch64/tst-sme-za-disable-fail.c | 67 +++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile index a78622cc35..2cf2903021 100644 --- a/sysdeps/aarch64/Makefile +++ b/sysdeps/aarch64/Makefile @@ -96,9 +96,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..c35e49de97 100644 --- a/sysdeps/aarch64/__arm_za_disable.S +++ b/sysdeps/aarch64/__arm_za_disable.S @@ -88,20 +88,10 @@ 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) - bl HIDDEN_JUMPTARGET (__libc_fatal) + b HIDDEN_JUMPTARGET (__libc_fatal) END (__libc_arm_za_disable) .section .rodata diff --git a/sysdeps/aarch64/tst-sme-helper.h b/sysdeps/aarch64/tst-sme-helper.h index 2ae2cc2f47..fbf1d4772c 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_maybe_unused__ get_svcr (void) { register unsigned long x0 asm ("x0"); @@ -34,7 +34,7 @@ get_svcr (void) } /* Returns tpidr2. */ -static void * +static __attribute_maybe_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_maybe_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_maybe_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_maybe_unused__ __attribute__ ((noinline)) 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_maybe_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>