[PATCH 2/2] aarch64: update tests for SME
Yury Khrustalev
yury.khrustalev@arm.com
Wed Apr 30 15:49:01 GMT 2025
Add test that checks that ZA state is disabled after setjmp and sigsetjmp
Update existing SME test that uses setjmp
---
sysdeps/aarch64/Makefile | 4 +-
sysdeps/aarch64/tst-sme-helper.h | 39 +++++++++++++++++
sysdeps/aarch64/tst-sme-jmp.c | 28 ++----------
sysdeps/aarch64/tst-sme-za-state.c | 68 ++++++++++++++++++++++++++++++
4 files changed, 114 insertions(+), 25 deletions(-)
create mode 100644 sysdeps/aarch64/tst-sme-helper.h
create mode 100644 sysdeps/aarch64/tst-sme-za-state.c
diff --git a/sysdeps/aarch64/Makefile b/sysdeps/aarch64/Makefile
index 4b7f8a5c07..2cb8f6cebc 100644
--- a/sysdeps/aarch64/Makefile
+++ b/sysdeps/aarch64/Makefile
@@ -75,7 +75,9 @@ sysdep_routines += \
__alloc_gcs
tests += \
- tst-sme-jmp
+ tst-sme-jmp \
+ tst-sme-za-state \
+ # tests
endif
ifeq ($(subdir),malloc)
diff --git a/sysdeps/aarch64/tst-sme-helper.h b/sysdeps/aarch64/tst-sme-helper.h
new file mode 100644
index 0000000000..09dd659aed
--- /dev/null
+++ b/sysdeps/aarch64/tst-sme-helper.h
@@ -0,0 +1,39 @@
+/* Utility functions for SME tests.
+ Copyright (C) 2025 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/>. */
+
+/* Read SVCR to get SM (bit0) and ZA (bit1) state. */
+static unsigned long
+get_svcr (void)
+{
+ register unsigned long x0 asm ("x0");
+ asm volatile (
+ ".inst 0xd53b4240 /* mrs x0, svcr */\n"
+ : "=r" (x0));
+ return x0;
+}
+
+/* Returns tpidr2. */
+static void *
+get_tpidr2 (void)
+{
+ register unsigned long x0 asm ("x0");
+ asm volatile (
+ ".inst 0xd53bd0a0 /* mrs x0, tpidr2_el0 */\n"
+ : "=r"(x0) :: "memory");
+ return (void *) x0;
+}
diff --git a/sysdeps/aarch64/tst-sme-jmp.c b/sysdeps/aarch64/tst-sme-jmp.c
index 62c419f6c1..0be11d44f5 100644
--- a/sysdeps/aarch64/tst-sme-jmp.c
+++ b/sysdeps/aarch64/tst-sme-jmp.c
@@ -27,6 +27,8 @@
#include <support/support.h>
#include <support/test-driver.h>
+#include "tst-sme-helper.h"
+
struct blk {
void *za_save_buffer;
uint16_t num_za_save_slices;
@@ -56,17 +58,6 @@ start_za (void)
".inst 0xd503457f /* smstart za */");
}
-/* Read SVCR to get SM (bit0) and ZA (bit1) state. */
-static unsigned long
-get_svcr (void)
-{
- register unsigned long x0 asm ("x0");
- asm volatile (
- ".inst 0xd53b4240 /* mrs x0, svcr */\n"
- : "=r" (x0));
- return x0;
-}
-
/* Load data into ZA byte by byte from p. */
static void __attribute__ ((noinline))
load_za (const void *p)
@@ -97,17 +88,6 @@ set_tpidr2 (struct blk *blk)
:: "r"(x0) : "memory");
}
-/* Returns tpidr2. */
-static void *
-get_tpidr2 (void)
-{
- register unsigned long x0 asm ("x0");
- asm volatile (
- ".inst 0xd53bd0a0 /* mrs x0, tpidr2_el0 */\n"
- : "=r"(x0) :: "memory");
- return (void *) x0;
-}
-
static void
print_data(const char *msg, void *p)
{
@@ -168,8 +148,8 @@ longjmp_test (void)
{
p = get_tpidr2 ();
printf ("before longjmp: tp2 = %p\n", p);
- if (p != &blk)
- FAIL_EXIT1 ("tpidr2 is clobbered");
+ if (p != NULL)
+ FAIL_EXIT1 ("tpidr2 has not been reset to null");
do_longjmp (env);
FAIL_EXIT1 ("longjmp returned");
}
diff --git a/sysdeps/aarch64/tst-sme-za-state.c b/sysdeps/aarch64/tst-sme-za-state.c
new file mode 100644
index 0000000000..b547674d76
--- /dev/null
+++ b/sysdeps/aarch64/tst-sme-za-state.c
@@ -0,0 +1,68 @@
+/* Test for SME ZA state being cleared on setjmp and longjmp.
+ Copyright (C) 2025 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 <stdio.h>
+#include <setjmp.h>
+#include <sys/auxv.h>
+
+#include <support/check.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+
+#include "tst-sme-helper.h"
+
+static void
+check_sme_za_state (void)
+{
+ unsigned long svcr = get_svcr ();
+ void *tpidr2 = get_tpidr2 ();
+ printf ("svcr = %016lx\n", svcr);
+ printf ("tpidr2 = %016lx\n", (unsigned long)tpidr2);
+ TEST_COMPARE (svcr, 0);
+ TEST_COMPARE ((unsigned long)tpidr2, 0);
+}
+
+static void
+run(void)
+{
+ jmp_buf buf;
+ int ret;
+ if ((ret = setjmp (buf)) == 0)
+ {
+ printf ("ready for long jump\n");
+ check_sme_za_state ();
+ longjmp (buf, 42);
+ TEST_VERIFY (false); // unreachable
+ __builtin_unreachable ();
+ }
+ TEST_COMPARE (ret, 42);
+ printf ("completed long jump\n");
+ check_sme_za_state ();
+}
+
+static int
+do_test (void)
+{
+ unsigned long hwcap2 = getauxval (AT_HWCAP2);
+ if ((hwcap2 & HWCAP2_SME) == 0)
+ return EXIT_UNSUPPORTED;
+ run ();
+ return 0;
+}
+
+#include <support/test-driver.c>
--
2.39.5
More information about the Libc-alpha
mailing list