From f589de083951b2e602930bcce07f5867215c4097 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 21 Mar 2018 16:19:43 -0400 Subject: [PATCH] Rework Glibc sysconf code It looks like the 0 return value for _SC_LEVEL1_DCACHE_LINESIZE is not a 1-off problem with PPC. It appears Glibc regularly returns 0 instead of failure. Also see https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c. We were OK before the change. The difference now is, we expect all Glibc queries to misbehave --- cpu.cpp | 117 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/cpu.cpp b/cpu.cpp index 875ddd57..b9511142 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -31,10 +31,10 @@ # include #else #ifndef AT_HWCAP -#define AT_HWCAP 16 +# define AT_HWCAP 16 #endif #ifndef AT_HWCAP2 -#define AT_HWCAP2 26 +# define AT_HWCAP2 26 #endif unsigned long int getauxval(unsigned long int) { return 0; } #endif @@ -299,7 +299,7 @@ void DetectX86Features() } } - if (!g_cacheLineSize) + if (g_cacheLineSize == 0) g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; *const_cast(&g_x86DetectionDone) = true; @@ -374,21 +374,21 @@ extern bool CPU_ProbePMULL(); inline bool CPU_QueryNEON() { #if defined(__ANDROID__) && defined(__aarch64__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && - (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD) != 0)) return true; #elif defined(__ANDROID__) && defined(__arm__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)) return true; #elif defined(__linux__) && defined(__aarch64__) - if (getauxval(AT_HWCAP) & HWCAP_ASIMD) + if ((getauxval(AT_HWCAP) & HWCAP_ASIMD) != 0) return true; #elif defined(__linux__) && defined(__aarch32__) - if (getauxval(AT_HWCAP2) & HWCAP2_ASIMD) + if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0) return true; #elif defined(__linux__) && defined(__arm__) - if (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) + if ((getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0) return true; #elif defined(__APPLE__) && defined(__aarch64__) // Core feature set for Aarch32 and Aarch64. @@ -400,18 +400,18 @@ inline bool CPU_QueryNEON() inline bool CPU_QueryCRC32() { #if defined(__ANDROID__) && defined(__aarch64__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && - (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_CRC32)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_CRC32) != 0)) return true; #elif defined(__ANDROID__) && defined(__aarch32__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_CRC32)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0)&& + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_CRC32) != 0)) return true; #elif defined(__linux__) && defined(__aarch64__) - if (getauxval(AT_HWCAP) & HWCAP_CRC32) + if ((getauxval(AT_HWCAP) & HWCAP_CRC32) != 0) return true; #elif defined(__linux__) && defined(__aarch32__) - if (getauxval(AT_HWCAP2) & HWCAP2_CRC32) + if ((getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0) return true; #elif defined(__APPLE__) && defined(__aarch64__) // No compiler support. CRC intrinsics result in a failed compiled. @@ -423,18 +423,18 @@ inline bool CPU_QueryCRC32() inline bool CPU_QueryPMULL() { #if defined(__ANDROID__) && defined(__aarch64__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && - (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_PMULL)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0)&& + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_PMULL) != 0)) return true; #elif defined(__ANDROID__) && defined(__aarch32__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_PMULL)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_PMULL) != 0)) return true; #elif defined(__linux__) && defined(__aarch64__) - if (getauxval(AT_HWCAP) & HWCAP_PMULL) + if ((getauxval(AT_HWCAP) & HWCAP_PMULL) != 0) return true; #elif defined(__linux__) && defined(__aarch32__) - if (getauxval(AT_HWCAP2) & HWCAP2_PMULL) + if ((getauxval(AT_HWCAP2) & HWCAP2_PMULL) != 0) return true; #elif defined(__APPLE__) && defined(__aarch64__) // No compiler support. PMULL intrinsics result in a failed compiled. @@ -446,18 +446,18 @@ inline bool CPU_QueryPMULL() inline bool CPU_QueryAES() { #if defined(__ANDROID__) && defined(__aarch64__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && - (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0)&& + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES) != 0)) return true; #elif defined(__ANDROID__) && defined(__aarch32__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0)&& + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_AES) != 0)) return true; #elif defined(__linux__) && defined(__aarch64__) - if (getauxval(AT_HWCAP) & HWCAP_AES) + if ((getauxval(AT_HWCAP) & HWCAP_AES) != 0) return true; #elif defined(__linux__) && defined(__aarch32__) - if (getauxval(AT_HWCAP2) & HWCAP2_AES) + if ((getauxval(AT_HWCAP2) & HWCAP2_AES) != 0) return true; #elif defined(__APPLE__) && defined(__aarch64__) // http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios @@ -481,18 +481,18 @@ inline bool CPU_QueryAES() inline bool CPU_QuerySHA1() { #if defined(__ANDROID__) && defined(__aarch64__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && - (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA1)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA1) != 0)) return true; #elif defined(__ANDROID__) && defined(__aarch32__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA1)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA1) != 0)) return true; #elif defined(__linux__) && defined(__aarch64__) - if (getauxval(AT_HWCAP) & HWCAP_SHA1) + if ((getauxval(AT_HWCAP) & HWCAP_SHA1) != 0) return true; #elif defined(__linux__) && defined(__aarch32__) - if (getauxval(AT_HWCAP2) & HWCAP2_SHA1) + if ((getauxval(AT_HWCAP2) & HWCAP2_SHA1) != 0) return true; #elif defined(__APPLE__) && defined(__aarch64__) // http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios @@ -516,18 +516,18 @@ inline bool CPU_QuerySHA1() inline bool CPU_QuerySHA2() { #if defined(__ANDROID__) && defined(__aarch64__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) && - (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA2)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0)&& + ((android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_SHA2) != 0)) return true; #elif defined(__ANDROID__) && defined(__aarch32__) - if ((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) && - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA2)) + if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && + ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_SHA2) != 0)) return true; #elif defined(__linux__) && defined(__aarch64__) - if (getauxval(AT_HWCAP) & HWCAP_SHA2) + if ((getauxval(AT_HWCAP) & HWCAP_SHA2) != 0) return true; #elif defined(__linux__) && defined(__aarch32__) - if (getauxval(AT_HWCAP2) & HWCAP2_SHA2) + if ((getauxval(AT_HWCAP2) & HWCAP2_SHA2) != 0) return true; #elif defined(__APPLE__) && defined(__aarch64__) // http://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios @@ -560,12 +560,13 @@ void DetectArmFeatures() g_hasSHA2 = CPU_QuerySHA2() || CPU_ProbeSHA2(); #if defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE) - g_cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + // Glibc does not implement on some platforms. The runtime returns 0 instead of error. + // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c + int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + if (cacheLineSize > 0) + g_cacheLineSize = cacheLineSize; #endif - if (!g_cacheLineSize) - g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - *const_cast(&g_ArmDetectionDone) = true; } @@ -601,7 +602,7 @@ extern bool CPU_ProbeSHA512(); inline bool CPU_QueryAltivec() { #if defined(__linux__) - if (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) + if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0) return true; #elif defined(_AIX) if (__power_vmx() != 0) @@ -626,7 +627,7 @@ inline bool CPU_QueryPower7() { // Power7 and ISA 2.06 #if defined(__linux__) - if (getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06 != 0) + if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0) return true; #elif defined(_AIX) if (__power_7_andup() != 0) @@ -639,7 +640,7 @@ inline bool CPU_QueryPower8() { // Power8 and ISA 2.07 provide in-core crypto. #if defined(__linux__) - if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07 != 0) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0) return true; #elif defined(_AIX) if (__power_8_andup() != 0) @@ -653,7 +654,7 @@ inline bool CPU_QueryAES() // Power8 and ISA 2.07 provide in-core crypto. Glibc // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. #if defined(__linux__) - if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO != 0) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) return true; #elif defined(_AIX) if (__power_8_andup() != 0) @@ -667,7 +668,7 @@ inline bool CPU_QuerySHA256() // Power8 and ISA 2.07 provide in-core crypto. Glibc // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. #if defined(__linux__) - if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO != 0) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) return true; #elif defined(_AIX) if (__power_8_andup() != 0) @@ -680,7 +681,7 @@ inline bool CPU_QuerySHA512() // Power8 and ISA 2.07 provide in-core crypto. Glibc // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. #if defined(__linux__) - if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO != 0) + if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) return true; #elif defined(_AIX) if (__power_8_andup() != 0) @@ -701,17 +702,19 @@ void DetectPowerpcFeatures() g_hasSHA256 = CPU_QuerySHA256() || CPU_ProbeSHA256(); g_hasSHA512 = CPU_QuerySHA512() || CPU_ProbeSHA512(); -#if defined(_AIX) +#if defined(_AIX) && defined(SC_L1C_DLS) // /usr/include/sys/systemcfg.h - g_cacheLineSize = getsystemcfg(SC_L1C_DLS); + int cacheLineSize = getsystemcfg(SC_L1C_DLS); + if (cacheLineSize > 0) + g_cacheLineSize = cacheLineSize; #elif defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE) - // GCC112 CentOS 7 returns 0? - g_cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + // Glibc does not implement on some platforms. The runtime returns 0 instead of error. + // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c + int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); + if (cacheLineSize > 0) + g_cacheLineSize = cacheLineSize; #endif - if (g_cacheLineSize <= 0) - g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - *const_cast(&g_PowerpcDetectionDone) = true; }