From: Mark Kettenis Subject: Re: libcrypto: switch aarch64 CPU feature detection to elf_aux_info() To: Christian Weisgerber Cc: tech@openbsd.org, bcook@openbsd.org Date: Tue, 04 Aug 2026 19:53:34 +0200 > Date: Tue, 4 Aug 2026 19:30:11 +0200 > From: Christian Weisgerber > > 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 > 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 > -#include > +#include > > -#include > - > #include > #include > > @@ -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 > >