diff --git a/src/hwcaps.c b/src/hwcaps.c index 605f892..f44f6c3 100644 --- a/src/hwcaps.c +++ b/src/hwcaps.c @@ -68,13 +68,7 @@ static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type) { #elif defined(HAVE_DLFCN_H) // On Android we probe the system's C library for a 'getauxval' function and // call it if it exits, or return 0 for failure. This function is available -// since API level 20. -// -// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the edge -// case where some NDK developers use headers for a platform that is newer than -// the one really targetted by their application. This is typically done to use -// newer native APIs only when running on more recent Android versions, and -// requires careful symbol management. +// since API level 18. // // Note that getauxval() can't really be re-implemented here, because its // implementation does not parse /proc/self/auxv. Instead it depends on values diff --git a/src/impl_arm_linux_or_android.c b/src/impl_arm_linux_or_android.c index d110a15..997ef93 100644 --- a/src/impl_arm_linux_or_android.c +++ b/src/impl_arm_linux_or_android.c @@ -152,13 +152,14 @@ static void FixErrors(ArmInfo* const info, // https://crbug.com/341598. info->features.neon = false; break; - case 0x510006F2: - case 0x510006F3: - // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report - // IDIV support. - info->features.idiva = true; - info->features.idivt = true; - break; + } + + // Some Qualcomm Krait kernels forget to report IDIV support. + // https://github.com/torvalds/linux/commit/120ecfafabec382c4feb79ff159ef42a39b6d33b + if (info->implementer == 0x51 && info->architecture == 7 && + (info->part == 0x4d || info->part == 0x6f)) { + info->features.idiva = true; + info->features.idivt = true; } // Propagate cpu features. diff --git a/test/cpuinfo_arm_test.cc b/test/cpuinfo_arm_test.cc index 85ee7fb..ad7f4e8 100644 --- a/test/cpuinfo_arm_test.cc +++ b/test/cpuinfo_arm_test.cc @@ -327,6 +327,24 @@ CPU revision : 3)"); EXPECT_EQ(GetArmCpuId(&info), 0x510006f3); } +// The 2013 Nexus 7 (Qualcomm Krait) kernel configuration forgets to report IDIV +// support. +TEST(CpuinfoArmTest, Nexus7_2013_0x511006f0) { + ResetHwcaps(); + auto& fs = GetEmptyFilesystem(); + fs.CreateFile("/proc/cpuinfo", + R"(CPU implementer : 0x51 +CPU architecture: 7 +CPU variant : 0x1 +CPU part : 0x06f +CPU revision : 0)"); + const auto info = GetArmInfo(); + EXPECT_TRUE(info.features.idiva); + EXPECT_TRUE(info.features.idivt); + + EXPECT_EQ(GetArmCpuId(&info), 0x511006f0); +} + // The emulator-specific Android 4.2 kernel fails to report support for the // 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual // CPU implemented by the emulator.