[PATCH] Use getauxval system function for detecting ARM HW features
Jussi Kivilinna
jussi.kivilinna at iki.fi
Mon Apr 8 20:01:15 CEST 2019
* configure.ac: Add header check for 'sys/auxv.h'.
* src/hwf-arm.c [HAVE_SYS_AUXV_H]: Include 'sys/auxv.h'.
(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]: Use 'getauxval' to fetch HW capability
flags.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
0 files changed
diff --git a/configure.ac b/configure.ac
index 0a931f952..63a275079 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>"
diff --git a/src/hwf-arm.c b/src/hwf-arm.c
index a762b5eab..efbbd0c2d 100644
--- a/src/hwf-arm.c
+++ b/src/hwf-arm.c
@@ -23,6 +23,10 @@
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
+#include <errno.h>
+#ifdef HAVE_SYS_AUXV_H
+#include <sys/auxv.h>
+#endif
#include "g10lib.h"
#include "hwf-common.h"
@@ -47,15 +51,29 @@ struct feature_map_s {
#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 +90,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 +145,34 @@ get_hwcap(unsigned int *hwcap, unsigned int *hwcap2)
return 0;
}
+#ifdef HAVE_SYS_AUXV_H
+ 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 +185,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;
}
}
More information about the Gcrypt-devel
mailing list