summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2019-04-08 20:44:08 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2019-04-08 23:25:19 +0300
commit6812a2c5bd2d9129bfdf34f3daf89cd8543ed8e5 (patch)
tree4179a5991aafb6f4f1da1ab747defcd71c938b6b
parent04a6c3c7482dd1ecb5113a049b1765b0d5f212fb (diff)
downloadlibgcrypt-6812a2c5bd2d9129bfdf34f3daf89cd8543ed8e5.tar.gz
Use getauxval system function for detecting ARM HW features
* configure.ac: Add header check for 'sys/auxv.h'; Add function check for 'getauxval'. * src/hwf-arm.c [HAVE_SYS_AUXV_H && HAVE_GETAUXVAL]: Include 'sys/auxv.h'. (HAS_SYS_AT_HWCAP): Enable AT_HWCAP if have 'getauxval' in addition of __linux__. (AT_HWCAP, AT_HWCAP2, HWCAP_NEON, HWCAP2_AES, HWCAP2_PMULL) (HWCAP2_SHA1, HWCAP2_SHA2, HWCAP_ASIMD, HWCAP_AES) (HWCAP_PMULL, HWCAP_SHA1, HWCAP_SHA2): Define these macros only if not already defined. (get_hwcap) [HAVE_SYS_AUXV_H && HAVE_GETAUXVAL]: Use 'getauxval' to fetch HW capability flags. -- Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
-rw-r--r--configure.ac4
-rw-r--r--src/hwf-arm.c108
2 files changed, 88 insertions, 24 deletions
diff --git a/configure.ac b/configure.ac
index 0a931f95..b0d7f890 100644
--- a/configure.ac
+++ b/configure.ac
@@ -805,7 +805,7 @@ AC_SEARCH_LIBS(setsockopt, [nsl])
##################################
AC_HEADER_STDC
-AC_CHECK_HEADERS(unistd.h sys/select.h sys/msg.h)
+AC_CHECK_HEADERS(unistd.h sys/select.h sys/msg.h sys/auxv.h)
INSERT_SYS_SELECT_H=
if test x"$ac_cv_header_sys_select_h" = xyes; then
INSERT_SYS_SELECT_H=" include <sys/select.h>"
@@ -1806,7 +1806,7 @@ AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise)
# Other checks
AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4)
AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog)
-AC_CHECK_FUNCS(syscall fcntl ftruncate flockfile)
+AC_CHECK_FUNCS(syscall fcntl ftruncate flockfile getauxval)
AC_CHECK_FUNCS(explicit_bzero getentropy)
GNUPG_CHECK_MLOCK
diff --git a/src/hwf-arm.c b/src/hwf-arm.c
index a762b5ea..0f8f83f6 100644
--- a/src/hwf-arm.c
+++ b/src/hwf-arm.c
@@ -1,5 +1,5 @@
/* hwf-arm.c - Detect hardware features - ARM part
- * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ * Copyright (C) 2013,2019 Jussi Kivilinna <jussi.kivilinna@iki.fi>
*
* This file is part of Libgcrypt.
*
@@ -23,6 +23,10 @@
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
+#include <errno.h>
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)
+#include <sys/auxv.h>
+#endif
#include "g10lib.h"
#include "hwf-common.h"
@@ -32,8 +36,9 @@
#endif
#undef HAS_SYS_AT_HWCAP
-#undef HAS_PROC_CPUINFO
-#ifdef __linux__
+#if defined(__linux__) || \
+ (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL))
+#define HAS_SYS_AT_HWCAP 1
struct feature_map_s {
unsigned int hwcap_flag;
@@ -42,20 +47,31 @@ struct feature_map_s {
unsigned int hwf_flag;
};
-#define HAS_SYS_AT_HWCAP 1
-#define HAS_PROC_CPUINFO 1
-
#ifdef __arm__
-#define AT_HWCAP 16
-#define AT_HWCAP2 26
+#ifndef AT_HWCAP
+# define AT_HWCAP 16
+#endif
+#ifndef AT_HWCAP2
+# define AT_HWCAP2 26
+#endif
-#define HWCAP_NEON 4096
+#ifndef HWCAP_NEON
+# define HWCAP_NEON 4096
+#endif
-#define HWCAP2_AES 1
-#define HWCAP2_PMULL 2
-#define HWCAP2_SHA1 3
-#define HWCAP2_SHA2 4
+#ifndef HWCAP2_AES
+# define HWCAP2_AES 1
+#endif
+#ifndef HWCAP2_PMULL
+# define HWCAP2_PMULL 2
+#endif
+#ifndef HWCAP2_SHA1
+# define HWCAP2_SHA1 3
+#endif
+#ifndef HWCAP2_SHA2
+# define HWCAP2_SHA2 4
+#endif
static const struct feature_map_s arm_features[] =
{
@@ -72,14 +88,28 @@ static const struct feature_map_s arm_features[] =
#elif defined(__aarch64__)
-#define AT_HWCAP 16
-#define AT_HWCAP2 -1
+#ifndef AT_HWCAP
+# define AT_HWCAP 16
+#endif
+#ifndef AT_HWCAP2
+# define AT_HWCAP2 -1
+#endif
-#define HWCAP_ASIMD 2
-#define HWCAP_AES 8
-#define HWCAP_PMULL 16
-#define HWCAP_SHA1 32
-#define HWCAP_SHA2 64
+#ifndef HWCAP_ASIMD
+# define HWCAP_ASIMD 2
+#endif
+#ifndef HWCAP_AES
+# define HWCAP_AES 8
+#endif
+#ifndef HWCAP_PMULL
+# define HWCAP_PMULL 16
+#endif
+#ifndef HWCAP_SHA1
+# define HWCAP_SHA1 32
+#endif
+#ifndef HWCAP_SHA2
+# define HWCAP_SHA2 64
+#endif
static const struct feature_map_s arm_features[] =
{
@@ -113,6 +143,34 @@ get_hwcap(unsigned int *hwcap, unsigned int *hwcap2)
return 0;
}
+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)
+ errno = 0;
+ auxv.a_val = getauxval (AT_HWCAP);
+ if (errno == 0)
+ {
+ stored_hwcap |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+
+ if (AT_HWCAP2 >= 0)
+ {
+ errno = 0;
+ auxv.a_val = getauxval (AT_HWCAP2);
+ if (errno == 0)
+ {
+ stored_hwcap2 |= auxv.a_val;
+ hwcap_initialized = 1;
+ }
+ }
+
+ if (hwcap_initialized && (stored_hwcap || stored_hwcap2))
+ {
+ *hwcap = stored_hwcap;
+ *hwcap2 = stored_hwcap2;
+ return 0;
+ }
+#endif
+
f = fopen("/proc/self/auxv", "r");
if (!f)
{
@@ -125,13 +183,13 @@ get_hwcap(unsigned int *hwcap, unsigned int *hwcap2)
{
if (auxv.a_type == AT_HWCAP)
{
- stored_hwcap = auxv.a_val;
+ stored_hwcap |= auxv.a_val;
hwcap_initialized = 1;
}
if (auxv.a_type == AT_HWCAP2)
{
- stored_hwcap2 = auxv.a_val;
+ stored_hwcap2 |= auxv.a_val;
hwcap_initialized = 1;
}
}
@@ -168,6 +226,12 @@ detect_arm_at_hwcap(void)
return features;
}
+#endif
+
+#undef HAS_PROC_CPUINFO
+#ifdef __linux__
+#define HAS_PROC_CPUINFO 1
+
static unsigned int
detect_arm_proc_cpuinfo(unsigned int *broken_hwfs)
{