On 14.03.2019 08:41, Niels Möller wrote: > "Yuriy M. Kaminskiy" <[email protected]> writes: > >> When compiled for armv6+ and getauxval() is present (glibc 2.16+), >> avoid slow and unreliable /proc/cpuinfo parsing. >> >> E.g. /proc/cpuinfo contains junk with qemu-user and can be unavailable >> in some chroot environment. > > Do you know what's the preferred way to do this on android? Do we still > need /proc/cpuinfo, or are there any library facilities?
Google suggests https://developer.android.com/ndk/guides/cpu-features I have no experience with it. >> +#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16) >> +#include <sys/auxv.h> > > This part could be an AC_CHECK_HEADERS([sys/auxv.h]) in configure.ac. Hmm... musl also provides it, I'll move detection to configure; then again, musl does not define HWCAP_*, and I'm reluctant to fallback to <asm/hwcap.h> or define HWCAP_* myself, so practically it still works on glibc only. >> else >> { >> +#if defined(HAVE_GETAUXVAL) && __ARM_ARCH >= 6 > > Why the condition __ARM_ARCH >= 6? Is it because getauxval doesn't let us > make the distinction between arch_version 5 and 6? There are (const char *)getauxval(AT_PLATFORM); it is expected to be "v[45678][lb]"; probably, I should use it. Things that should be checked: arm (32bit) userland with aarch64/arm64 kernel. >> + unsigned long hwcap = getauxval(AT_HWCAP); >> + features->arch_version = __ARM_ARCH; > > Is it important to take the compile-time arch into account? The effect > (when it makes a difference at all) will be to force use of certain > features, even if runtime checks say we're running on an older arch. I wanted to limit change to cases I'm sure will work (e.g. on debian/armhf __ARM_ARCH is 7, on raspbian - 6; both are sufficient for nettle to use most optimized code); and don't touch anything "unusual". > Is the getauxval method missing a way to get cpu arch at runtime? In the > docs > (https://github.com/torvalds/linux/blob/master/arch/arm/include/uapi/asm/hwcap.h) > I don't see anything corresponding to the "CPU arcitecture" line in > /proc/cpuinfo. > > I'd be happier about getauxval if we could find a way to also get the > arch version without reading /proc/cpuinfo. But I don't think it's a > blocker for this change.
>From 184cc27c1592eea98f3bcb7e48a32bf97e126709 Mon Sep 17 00:00:00 2001 From: "Yuriy M. Kaminskiy" <[email protected]> Date: Sun, 10 Mar 2019 12:25:21 +0300 Subject: [PATCH] fat-arm.c: prefer getauxval() over /proc/cpuinfo parsing When getauxval() is present (glibc 2.16+), avoid slow and unreliable /proc/cpuinfo parsing. Use compile-time ARM archeticture as a fallback. Use VFPv3 as fallback to ARMv7 detection when AT_PLATFORM is not recognized (NEON implies VFPv3 with VFPD32; VFPv4 implies VFPv3; when NEON present, VFPv4 implies NEONv2; VFPv3 implies armv7) --- configure.ac | 4 ++++ fat-arm.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/configure.ac b/configure.ac index 4a482bdd..76fabfef 100644 --- a/configure.ac +++ b/configure.ac @@ -193,6 +193,10 @@ AC_CHECK_HEADERS([openssl/evp.h openssl/ecdsa.h],, [enable_openssl=no break]) +# For --enable-fat on arm +AC_CHECK_HEADERS([sys/auxv.h]) +AC_CHECK_FUNCS(getauxval) + # For use by the testsuite AC_CHECK_HEADERS([valgrind/memcheck.h]) AC_CHECK_HEADERS([dlfcn.h]) diff --git a/fat-arm.c b/fat-arm.c index 6e4c8622..cdc137a2 100644 --- a/fat-arm.c +++ b/fat-arm.c @@ -40,6 +40,15 @@ #include <stdlib.h> #include <string.h> +#ifdef HAVE_SYS_AUXV_H +#include <sys/auxv.h> +#if !defined(AT_HWCAP) || !defined(HWCAP_ARM_NEON) || !defined(AT_PLATFORM) +#undef HAVE_GETAUXVAL +#endif +#else +#undef HAVE_GETAUXVAL +#endif + #include "nettle-types.h" #include "aes-internal.h" @@ -64,7 +73,11 @@ static void get_arm_features (struct arm_features *features) { const char *s; +#if __ARM_ARCH > 5 /* use compile-time arch as fallback */ + features->arch_version = __ARM_ARCH; +#else features->arch_version = 5; +#endif features->have_neon = 0; s = secure_getenv (ENV_OVERRIDE); @@ -87,6 +100,24 @@ get_arm_features (struct arm_features *features) } else { +#if defined(HAVE_GETAUXVAL) + unsigned long hwcap = getauxval(AT_HWCAP); + const char *platform = (const char *)getauxval(AT_PLATFORM); + + if (platform != NULL && platform[0] == 'v' && + (platform[1] >= '0' && platform[1] <= '9') && + (platform[2] == 'l' || platform[2] == 'b')) + features->arch_version = platform[1] - '0'; + else + { + /* fallback to VFPv3 as a proxy for armv7 detection */ + if (features->arch_version < 7 && (hwcap & HWCAP_ARM_VFPv3)) + features->arch_version = 7; + } + + if ((hwcap & HWCAP_ARM_NEON)) + features->have_neon = 1; +#else FILE *f; char line[200]; int seen_arch = 0; @@ -132,6 +163,7 @@ get_arm_features (struct arm_features *features) features->have_neon = 1; } fclose (f); +#endif } } -- 2.11.0
_______________________________________________ nettle-bugs mailing list [email protected] http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs
