diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-06-24 21:46:15 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2018-06-24 22:46:15 +0200 |
commit | b0c6c9c17e8ff683d4d370750888f3755c64dadc (patch) | |
tree | cf78b025f51ca728765169307990f08c2ce09141 | |
parent | 51b19b7192f5be327ab4df486de56f03e1f85cab (diff) | |
download | gnutls-tmp-aarch64.tar.gz |
aarch64: use getauxval() if available to discover cpu capstmp-aarch64
This improves CPU detection by avoiding the parsing of
of a human-readable file and allows operation under debian
multilib qemu setup.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/accelerated/aarch64/aarch64-common.c | 69 |
2 files changed, 36 insertions, 35 deletions
diff --git a/configure.ac b/configure.ac index c01a5c259e..548abbeebd 100644 --- a/configure.ac +++ b/configure.ac @@ -336,7 +336,7 @@ fi AM_CONDITIONAL(HAVE_FORK, test "$ac_cv_func_fork" != "no") -AC_CHECK_FUNCS([__register_atfork secure_getenv],,) +AC_CHECK_FUNCS([__register_atfork secure_getenv getauxval],,) AC_ARG_ENABLE(seccomp-tests, AS_HELP_STRING([--enable-seccomp-tests], [unconditionally enable tests with seccomp]), diff --git a/lib/accelerated/aarch64/aarch64-common.c b/lib/accelerated/aarch64/aarch64-common.c index 11f6a7466e..c1beb206fa 100644 --- a/lib/accelerated/aarch64/aarch64-common.c +++ b/lib/accelerated/aarch64/aarch64-common.c @@ -28,7 +28,6 @@ #include "errors.h" #include "gnutls_int.h" #include <gnutls/crypto.h> -#include <c-ctype.h> #include "errors.h" #ifdef HAVE_LIBNETTLE # include <nettle/aes.h> /* for key generation in 192 and 256 bits */ @@ -37,6 +36,13 @@ #endif #include "aarch64-common.h" +#ifdef HAVE_GETAUXVAL +# include <sys/auxv.h> +# ifdef AT_HWCAP +# define USE_AUXVAL +# endif +#endif + #if defined(__GNUC__) __attribute__((visibility("hidden"))) #elif defined(__SUNPRO_C) @@ -59,41 +65,36 @@ static void capabilities_to_cpuid(unsigned capabilities) _gnutls_arm_cpuid_s |= capabilities; } +/* Correspond to asm/hwcap.h for aarch64 */ +#ifdef USE_AUXVAL +#define HWCAP_ASIMD (1 << 1) +#define HWCAP_AES (1 << 3) +#define HWCAP_PMULL (1 << 4) +#define HWCAP_SHA1 (1 << 5) +#define HWCAP_SHA2 (1 << 6) +#define HWCAP_SHA3 (1 << 17) +#define HWCAP_SHA512 (1 << 21) +#endif + static void discover_caps(unsigned int *caps) { - char line[512]; - char *p, *savep = NULL, *p2; - FILE *fp = fopen("/proc/cpuinfo", "r"); - - if (fp == NULL) - return; - - /* this is most likely linux-only */ - while(fgets(line, sizeof(line), fp) != NULL) { - if (strncmp(line, "Features", 8) == 0) { - p = strchr(line, ':'); - if (p) { - p++; - while (c_isspace(*p)) - p++; - - while((p2 = strtok_r(p, " ", &savep)) != NULL) { - if (strncmp(p2, "sha2", 4) == 0) - *caps |= ARMV8_SHA256; - else if (strncmp(p2, "sha1", 4) == 0) - *caps |= ARMV8_SHA1; - else if (strncmp(p2, "pmull", 5) == 0) - *caps |= ARMV8_PMULL; - else if (strncmp(p2, "aes", 3) == 0) - *caps |= ARMV8_AES; - p = NULL; - } - } - break; - } - } - - fclose(fp); +#ifdef USE_AUXVAL + unsigned long c; + + c = getauxval(AT_HWCAP); + if (c & HWCAP_ASIMD) + *caps |= ARMV7_NEON; + if (c & HWCAP_AES) + *caps |= ARMV8_AES; + if (c & HWCAP_PMULL) + *caps |= ARMV8_PMULL; + if (c & HWCAP_SHA1) + *caps |= ARMV8_SHA1; + if (c & HWCAP_SHA2) + *caps |= ARMV8_SHA256; + if (c & HWCAP_SHA512) + *caps |= ARMV8_SHA512; +#endif } static |