[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