From a05be441d8cd89b90d8d58e3a343a436dae377d0 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Mon, 30 Dec 2013 15:10:13 +0200 Subject: Parse /proc/cpuinfo for ARM HW features * src/hwf-arm.c [__linux__] (HAS_PROC_CPUINFO) (detect_arm_proc_cpuinfo): New. (_gcry_hwf_detect_arm) [HAS_PROC_CPUINFO]: Check '/proc/cpuinfo' for HW features. -- Some Linux platforms (read: Android) block read access to '/proc/self/auxv', which prevents NEON HW detection. Patch adds alternative check which parses '/proc/cpuinfo' which should be accessable by Android applications. Signed-off-by: Jussi Kivilinna --- src/hwf-arm.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'src/hwf-arm.c') diff --git a/src/hwf-arm.c b/src/hwf-arm.c index 80718945..dbbb607f 100644 --- a/src/hwf-arm.c +++ b/src/hwf-arm.c @@ -32,6 +32,7 @@ #endif #undef HAS_SYS_AT_HWCAP +#undef HAS_PROC_CPUINFO #ifdef __linux__ #define HAS_SYS_AT_HWCAP 1 @@ -94,6 +95,54 @@ detect_arm_at_hwcap(void) return features; } +#define HAS_PROC_CPUINFO 1 + +static unsigned int +detect_arm_proc_cpuinfo(void) +{ + char buf[1024]; /* large enough */ + char *str_features, *str_neon; + FILE *f; + int readlen, i; + static int cpuinfo_initialized = 0; + static unsigned int stored_cpuinfo_features; + + if (cpuinfo_initialized) + return stored_cpuinfo_features; + + f = fopen("/proc/cpuinfo", "r"); + if (!f) + return 0; + + memset (buf, 0, sizeof(buf)); + readlen = fread (buf, 1, sizeof(buf), f); + fclose (f); + if (readlen <= 0 || readlen > sizeof(buf)) + return 0; + + buf[sizeof(buf) - 1] = '\0'; + + cpuinfo_initialized = 1; + stored_cpuinfo_features = 0; + + /* Find features line. */ + str_features = strstr(buf, "Features"); + if (!str_features) + return stored_cpuinfo_features; + + /* Lines to strings. */ + for (i = 0; i < sizeof(buf); i++) + if (buf[i] == '\n') + buf[i] = '\0'; + + /* Check for NEON. */ + str_neon = strstr(str_features, " neon"); + if (str_neon && (str_neon[5] == ' ' || str_neon[5] == '\0')) + stored_cpuinfo_features |= HWF_ARM_NEON; + + return stored_cpuinfo_features; +} + #endif /* __linux__ */ unsigned int @@ -103,8 +152,10 @@ _gcry_hwf_detect_arm (void) #if defined (HAS_SYS_AT_HWCAP) ret |= detect_arm_at_hwcap (); -#else - ret |= 0; +#endif + +#if defined (HAS_PROC_CPUINFO) + ret |= detect_arm_proc_cpuinfo (); #endif #if defined(__ARM_NEON__) && defined(ENABLE_NEON_SUPPORT) -- cgit v1.2.1