summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2018-06-24 21:46:15 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2018-06-24 22:46:15 +0200
commitb0c6c9c17e8ff683d4d370750888f3755c64dadc (patch)
treecf78b025f51ca728765169307990f08c2ce09141
parent51b19b7192f5be327ab4df486de56f03e1f85cab (diff)
downloadgnutls-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.ac2
-rw-r--r--lib/accelerated/aarch64/aarch64-common.c69
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