diff options
| author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2019-04-08 20:44:08 +0300 |
|---|---|---|
| committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2019-04-08 23:25:19 +0300 |
| commit | 6812a2c5bd2d9129bfdf34f3daf89cd8543ed8e5 (patch) | |
| tree | 4179a5991aafb6f4f1da1ab747defcd71c938b6b | |
| parent | 04a6c3c7482dd1ecb5113a049b1765b0d5f212fb (diff) | |
| download | libgcrypt-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.ac | 4 | ||||
| -rw-r--r-- | src/hwf-arm.c | 108 |
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) { |
