Disable jit_memory_region_test tests on buggy kernels.
Test: jit_memory_region_test
Change-Id: I5339071ab1fcb9765a91015e33024d05774ac2b1
diff --git a/libartbase/base/utils.cc b/libartbase/base/utils.cc
index 65d02da..840216c 100644
--- a/libartbase/base/utils.cc
+++ b/libartbase/base/utils.cc
@@ -47,6 +47,7 @@
#if defined(__linux__)
#include <linux/unistd.h>
#include <sys/syscall.h>
+#include <sys/utsname.h>
#endif
#if defined(_WIN32)
@@ -154,6 +155,29 @@
#endif
+bool CacheOperationsMaySegFault() {
+#if defined(__linux__) && defined(__aarch64__)
+ // Avoid issue on older ARM64 kernels where data cache operations could be classified as writes
+ // and cause segmentation faults. This was fixed in Linux 3.11rc2:
+ //
+ // https://github.com/torvalds/linux/commit/db6f41063cbdb58b14846e600e6bc3f4e4c2e888
+ //
+ // This behaviour means we should avoid the dual view JIT on the device. This is just
+ // an issue when running tests on devices that have an old kernel.
+ static constexpr int kRequiredMajor = 3;
+ static constexpr int kRequiredMinor = 12;
+ struct utsname uts;
+ int major, minor;
+ if (uname(&uts) != 0 ||
+ strcmp(uts.sysname, "Linux") != 0 ||
+ sscanf(uts.release, "%d.%d", &major, &minor) != 2 ||
+ (major < kRequiredMajor || (major == kRequiredMajor && minor < kRequiredMinor))) {
+ return true;
+ }
+#endif
+ return false;
+}
+
pid_t GetTid() {
#if defined(__APPLE__)
uint64_t owner;
diff --git a/libartbase/base/utils.h b/libartbase/base/utils.h
index f434cb4..ba95331 100644
--- a/libartbase/base/utils.h
+++ b/libartbase/base/utils.h
@@ -116,6 +116,9 @@
// Flush CPU caches. Returns true on success, false if flush failed.
WARN_UNUSED bool FlushCpuCaches(void* begin, void* end);
+// On some old kernels, a cache operation may segfault.
+WARN_UNUSED bool CacheOperationsMaySegFault();
+
template <typename T>
constexpr PointerSize ConvertToPointerSize(T any) {
if (any == 4 || any == 8) {