[PATCH v2] AArch64: Add ifunc masking tunable
Yury Khrustalev
yury.khrustalev@arm.com
Mon Jul 6 09:04:12 GMT 2026
Good morning Wilco,
On Fri, Jul 03, 2026 at 03:26:04PM +0000, Wilco Dijkstra wrote:
> 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?
Some comments below.
>
> ---
>
> 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
> -
OK.
> @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 {
Perhaps, use another name like 'hwcapsoff' or 'hwfeatoff'?
> 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
This test is still useful and we shouldn't delete it, it should just use the
new tunable. This test had been added to check for the failure to parse
string tunable from a static PIE program.
> 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
>
> ...
>
> +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;
> }
This serves to prevent certain flags to be set based on hardware
information for flags that affect performance via selecting an ifunc
implementation. AFAIK, the idea is to avoid changing flags that affect
security.
I think this is the right approach and should simplify testing, however
in theory it is possible that a security related ifunc choice will be
based on the value of midr_el1, and this patch would allow to by-pass
this. Maybe it's unlikely?
>
> ...
>
> @@ -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));
Probably a comment is needed that this tunable processing should always
remain at the bottom of this function?
Thanks,
Yury
More information about the Libc-alpha
mailing list