summaryrefslogtreecommitdiff
path: root/src/hwf-arm.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-12-30 15:10:13 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2013-12-30 15:10:13 +0200
commita05be441d8cd89b90d8d58e3a343a436dae377d0 (patch)
treed51122c3ef8c2987ba044b97e1ba145bdf5932f9 /src/hwf-arm.c
parentbbcb12187afb1756cb27296166b57fa19ee45d4d (diff)
downloadlibgcrypt-a05be441d8cd89b90d8d58e3a343a436dae377d0.tar.gz
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 <jussi.kivilinna@iki.fi>
Diffstat (limited to 'src/hwf-arm.c')
-rw-r--r--src/hwf-arm.c55
1 files changed, 53 insertions, 2 deletions
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)