[PATCH v2] AArch64: Add ifunc masking tunable
Wilco Dijkstra
Wilco.Dijkstra@arm.com
Fri Jul 3 15:26:04 GMT 2026
v2: Use hwcaps tunable after internal review comments from Yury
Remove the glibc.cpu.name tunable since it's unused and out of date.
Add support for glibc.cpu.hwcaps to adjust ifunc selection for debugging
and benchmarking (undocumented since this is for developers only).
Only allow disabling of features that are (a) used by ifuncs, (b) safe
to disable to a more generic ifunc without any security impact.
OK for commit?
---
diff --git a/manual/tunables.texi b/manual/tunables.texi
index e1d9fbae9cebe961fe45203251a761c3323a9917..17ff92501d0e0fcbb47512589289f933f1e82119 100644
--- a/manual/tunables.texi
+++ b/manual/tunables.texi
@@ -469,16 +469,6 @@ indicates that the process may use device memory.
This tunable is specific to powerpc, powerpc64 and powerpc64le.
@end deftp
-@deftp Tunable glibc.cpu.name
-The @code{glibc.cpu.name=xxx} tunable allows the user to tell @theglibc{} to
-assume that the CPU is @code{xxx} where xxx may have one of these values:
-@code{generic}, @code{thunderxt88}, @code{thunderx2t99},
-@code{thunderx2t99p1}, @code{ares}, @code{emag}, @code{kunpeng},
-@code{a64fx}.
-
-This tunable is specific to aarch64.
-@end deftp
-
@deftp Tunable glibc.cpu.x86_data_cache_size
The @code{glibc.cpu.x86_data_cache_size} tunable allows the user to set
data cache size in bytes for use in memory and string routines.
diff --git a/sysdeps/aarch64/dl-tunables.list b/sysdeps/aarch64/dl-tunables.list
index a2ccba0b293a2d728ec6986f7ddd5b9793c1de17..c876f3fe0d4891be425f0c022e4adcaa11f86af4 100644
--- a/sysdeps/aarch64/dl-tunables.list
+++ b/sysdeps/aarch64/dl-tunables.list
@@ -18,7 +18,7 @@
glibc {
cpu {
- name {
+ hwcaps {
type: STRING
}
aarch64_bti {
diff --git a/sysdeps/unix/sysv/linux/aarch64/Makefile b/sysdeps/unix/sysv/linux/aarch64/Makefile
index d1fcb48aa250dffd8b7e5b41f5b290512dc797e2..7e17e7741f8ecd26a71dbc0ec78c50dfc7f31fcb 100644
--- a/sysdeps/unix/sysv/linux/aarch64/Makefile
+++ b/sysdeps/unix/sysv/linux/aarch64/Makefile
@@ -9,16 +9,6 @@ modules-names += \
LDFLAGS-tst-tlsdesc-pac = -rdynamic
$(objpfx)tst-tlsdesc-pac.out: $(objpfx)tst-tlsdesc-pac-mod.so
-
-ifeq (yes,$(enable-static-pie))
-tests += \
- tst-cpu-tunable-static-pie \
- # tests
-tests-static += \
- tst-cpu-tunable-static-pie \
- # tests-static
-tst-cpu-tunable-static-pie-TUNABLES = glibc.cpu.name=generic
-endif
endif
ifeq ($(subdir),misc)
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
index 9a87332ac49c0272930200ece5276eb5a4a2fae4..9be1b8e2264ffd00d98a82c1638f98394b3a96ca 100644
--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
@@ -33,56 +33,39 @@
to see when pointer have been correctly tagged. */
#define MTE_ALLOWED_TAGS (0xfffe << PR_MTE_TAG_SHIFT)
-static const char cpu_list_name[] = {
- "kunpeng920\0"
- "kunpeng950\0"
- "a64fx\0"
- "generic\0",
-};
-
-static const uint64_t cpu_list_midr[] = {
- 0x481FD010,
- 0x480FD060,
- 0x460F0010,
- 0x0,
-};
-
-static uint64_t
-get_midr_from_mcpu (const struct tunable_str_t *mcpu)
+static void
+TUNABLE_CALLBACK (set_hwcaps) (tunable_val_t *val)
{
- const char *name = cpu_list_name;
- size_t offset = 0;
- for (int i = 0; i < array_length (cpu_list_midr); i++)
+ struct cpu_features *cpu_features = &GLRO(dl_aarch64_cpu_features);
+ struct tunable_str_comma_state_t cs;
+ tunable_str_comma_init (&cs, val);
+
+ struct tunable_str_comma_t n;
+ while (tunable_str_comma_next (&cs, &n))
{
- size_t len = strlen (name);
- if (tunable_strcmp (mcpu, cpu_list_name + offset, len))
- return cpu_list_midr[i];
- offset += len;
+ /* Support disabling of features to select more generic ifuncs. */
+ if (!n.disable)
+ continue;
+ if (tunable_str_comma_strcmp_cte (&n, "midr"))
+ cpu_features->midr_el1 = 0;
+ else if (tunable_str_comma_strcmp_cte (&n, "zva"))
+ cpu_features->zva_size = 0;
+ else if (tunable_str_comma_strcmp_cte (&n, "sve"))
+ cpu_features->sve = false;
+ else if (tunable_str_comma_strcmp_cte (&n, "sve2"))
+ cpu_features->sve2 = false;
+ else if (tunable_str_comma_strcmp_cte (&n, "mops"))
+ cpu_features->mops = false;
}
- return UINT64_MAX;
}
static inline void
init_cpu_features (struct cpu_features *cpu_features)
{
- register uint64_t midr = UINT64_MAX;
-
- /* Get the tunable override. */
- const struct tunable_str_t *mcpu = TUNABLE_GET (glibc, cpu, name,
- struct tunable_str_t *,
- NULL);
- if (mcpu != NULL)
- midr = get_midr_from_mcpu (mcpu);
-
- /* If there was no useful tunable override, query the MIDR if the kernel
- allows it. */
- if (midr == UINT64_MAX)
- {
- if (GLRO (dl_hwcap) & HWCAP_CPUID)
- asm volatile ("mrs %0, midr_el1" : "=r"(midr));
- else
- midr = 0;
- }
+ uint64_t midr = 0;
+
+ if (GLRO (dl_hwcap) & HWCAP_CPUID)
+ asm volatile ("mrs %0, midr_el1" : "=r"(midr));
cpu_features->midr_el1 = midr;
@@ -108,4 +91,7 @@ init_cpu_features (struct cpu_features *cpu_features)
if (GLRO (dl_hwcap) & HWCAP_GCS)
/* GCS status may be updated later by binary compatibility checks. */
GL (dl_aarch64_gcs) = TUNABLE_GET (glibc, cpu, aarch64_gcs, uint64_t, 0);
+
+ TUNABLE_GET (glibc, cpu, hwcaps, tunable_val_t *,
+ TUNABLE_CALLBACK (set_hwcaps));
}
diff --git a/sysdeps/unix/sysv/linux/aarch64/tst-cpu-tunable-static-pie.c b/sysdeps/unix/sysv/linux/aarch64/tst-cpu-tunable-static-pie.c
deleted file mode 100644
index 561eaf3bdb07b6fa03975e3a2fcf55fe17d34702..0000000000000000000000000000000000000000
--- a/sysdeps/unix/sysv/linux/aarch64/tst-cpu-tunable-static-pie.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Test that the glibc.cpu.name tunable is parsed correctly during early
- startup of a static PIE binary (bug 34205).
- 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/>. */
-
-static int
-do_test (void)
-{
- return 0;
-}
-
-#include <support/test-driver.c>
More information about the Libc-alpha
mailing list