Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: libcrypto: switch aarch64 CPU feature detection to elf_aux_info()
To:
Christian Weisgerber <naddy@mips.inka.de>
Cc:
tech@openbsd.org, bcook@openbsd.org
Date:
Tue, 04 Aug 2026 19:53:34 +0200

Download raw body.

Thread
> Date: Tue, 4 Aug 2026 19:30:11 +0200
> From: Christian Weisgerber <naddy@mips.inka.de>
> 
> The aarch64 runtime environment provides pre-parsed CPU feature
> capabilities for free.  We can just grab them with elf_aux_info()
> and no longer need to read the AA64ISAR0 register with sysctl or
> extract the bit fields.
> 
> OK?

Looks good to me; ok kettenis@

> Hint for -portable: This builds as-is on FreeBSD, too.

And this could be easily adapted for Linux by implementing
elf_aux_info() as a wrapper around getauxval() on that platform.

> -----------------------------------------------
> commit fa0e19296490832c8f496272bd150d14d170fb50
> from: Christian Weisgerber <naddy@mips.inka.de>
> date: Tue Aug  4 17:10:07 2026 UTC
>  
>  switch aarch64 CPU feature detection to elf_aux_info()
>  
> diff b2b8205756684c6db49759a3153d75acd569191f fa0e19296490832c8f496272bd150d14d170fb50
> commit - b2b8205756684c6db49759a3153d75acd569191f
> commit + fa0e19296490832c8f496272bd150d14d170fb50
> blob - b31a50ef7530b47b579bcaae6b551fd22bf5a861
> blob + b9e12776a66281cc4e674de3e80f4a0c9991c89d
> --- lib/libcrypto/arch/aarch64/crypto_cpu_caps.c
> +++ lib/libcrypto/arch/aarch64/crypto_cpu_caps.c
> @@ -15,11 +15,8 @@
>   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
>  
> -#include <sys/types.h>
> -#include <sys/sysctl.h>
> +#include <sys/auxv.h>
>  
> -#include <machine/cpu.h>
> -
>  #include <stddef.h>
>  #include <stdio.h>
>  
> @@ -28,70 +25,29 @@
>  /* Machine dependent CPU capabilities. */
>  uint64_t crypto_cpu_caps_aarch64;
>  
> -static inline uint64_t
> -extract_bits(uint64_t val, int start, int end)
> -{
> -	return (val >> end) & (1ULL << (1 + start - end)) - 1;
> -}
> -
> -static uint64_t
> -parse_isar0(uint64_t isar0)
> -{
> -	uint64_t caps = 0;
> -	uint64_t feature;
> -
> -	/* AES - bits [7:4] */
> -	feature = extract_bits(isar0, 7, 4);
> -	if (feature >= 1)
> -		caps |= CRYPTO_CPU_CAPS_AARCH64_AES;
> -	if (feature >= 2)
> -		caps |= CRYPTO_CPU_CAPS_AARCH64_PMULL;
> -
> -	/* SHA1 - bits [11:8] */
> -	feature = extract_bits(isar0, 11, 8);
> -	if (feature >= 1)
> -		caps |= CRYPTO_CPU_CAPS_AARCH64_SHA1;
> -
> -	/* SHA2 - bits [15:12] */
> -	feature = extract_bits(isar0, 15, 12);
> -	if (feature >= 1)
> -		caps |= CRYPTO_CPU_CAPS_AARCH64_SHA2;
> -	if (feature >= 2)
> -		caps |= CRYPTO_CPU_CAPS_AARCH64_SHA512;
> -
> -	/* SHA3 - bits [35:32] */
> -	feature = extract_bits(isar0, 35, 32);
> -	if (feature >= 1)
> -		caps |= CRYPTO_CPU_CAPS_AARCH64_SHA3;
> -
> -	return caps;
> -}
> -
> -static int
> -read_isar0(uint64_t *isar0)
> -{
> -	uint64_t isar;
> -	int mib[2];
> -	size_t len;
> -
> -	mib[0] = CTL_MACHDEP;
> -	mib[1] = CPU_ID_AA64ISAR0;
> -	len = sizeof(isar);
> -	if (sysctl(mib, 2, &isar, &len, NULL, 0) == -1)
> -		return 0;
> -
> -	*isar0 = isar;
> -
> -	return 1;
> -}
> -
>  void
>  crypto_cpu_caps_init(void)
>  {
> -	uint64_t isar = 0;
> +	unsigned long hwcap;
>  
> -	if (!read_isar0(&isar))
> +	if (elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) != 0)
>  		return;
>  
> -	crypto_cpu_caps_aarch64 = parse_isar0(isar);
> +	if (hwcap & HWCAP_AES)
> +		crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_AES;
> +
> +	if (hwcap & HWCAP_PMULL)
> +		crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_PMULL;
> +
> +	if (hwcap & HWCAP_SHA1)
> +		crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA1;
> +
> +	if (hwcap & HWCAP_SHA2)
> +		crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA2;
> +
> +	if (hwcap & HWCAP_SHA512)
> +		crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA512;
> +
> +	if (hwcap & HWCAP_SHA3)
> +		crypto_cpu_caps_aarch64 |= CRYPTO_CPU_CAPS_AARCH64_SHA3;
>  }
> 
> -- 
> Christian "naddy" Weisgerber                          naddy@mips.inka.de
> 
>