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) {
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 9e36888..3595c73 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -265,6 +265,12 @@
return; \
}
+#define TEST_DISABLED_FOR_KERNELS_WITH_CACHE_SEGFAULT() \
+ if (CacheOperationsMaySegFault()) { \
+ printf("WARNING: TEST DISABLED ON KERNEL THAT SEGFAULT ON CACHE OPERATIONS\n"); \
+ return; \
+ }
+
} // namespace art
#endif // ART_RUNTIME_COMMON_RUNTIME_TEST_H_
diff --git a/runtime/jit/jit_memory_region.cc b/runtime/jit/jit_memory_region.cc
index b3c2d7e..c23172c 100644
--- a/runtime/jit/jit_memory_region.cc
+++ b/runtime/jit/jit_memory_region.cc
@@ -17,7 +17,6 @@
#include "jit_memory_region.h"
#include <fcntl.h>
-#include <sys/utsname.h>
#include <unistd.h>
#include <android-base/unique_fd.h>
@@ -488,29 +487,6 @@
#if defined(__BIONIC__) && defined(ART_TARGET)
// The code below only works on bionic on target.
-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;
-}
-
int JitMemoryRegion::CreateZygoteMemory(size_t capacity, std::string* error_msg) {
if (CacheOperationsMaySegFault()) {
// Zygote JIT requires dual code mappings by design. We can only do this if the cache flush
diff --git a/runtime/jit/jit_memory_region_test.cc b/runtime/jit/jit_memory_region_test.cc
index e99ff70..2049611 100644
--- a/runtime/jit/jit_memory_region_test.cc
+++ b/runtime/jit/jit_memory_region_test.cc
@@ -26,6 +26,8 @@
#include "base/globals.h"
#include "base/memfd.h"
+#include "base/utils.h"
+#include "common_runtime_test.h"
namespace art {
namespace jit {
@@ -53,6 +55,8 @@
class TestZygoteMemory : public testing::Test {
public:
void BasicTest() {
+ // Zygote JIT memory only works on kernels that don't segfault on flush.
+ TEST_DISABLED_FOR_KERNELS_WITH_CACHE_SEGFAULT();
std::string error_msg;
size_t size = kPageSize;
android::base::unique_fd fd(JitMemoryRegion::CreateZygoteMemory(size, &error_msg));
@@ -104,6 +108,8 @@
}
void TestUnmapWritableAfterFork() {
+ // Zygote JIT memory only works on kernels that don't segfault on flush.
+ TEST_DISABLED_FOR_KERNELS_WITH_CACHE_SEGFAULT();
std::string error_msg;
size_t size = kPageSize;
int32_t* addr = nullptr;
@@ -199,6 +205,8 @@
}
void TestMadviseDontFork() {
+ // Zygote JIT memory only works on kernels that don't segfault on flush.
+ TEST_DISABLED_FOR_KERNELS_WITH_CACHE_SEGFAULT();
std::string error_msg;
size_t size = kPageSize;
int32_t* addr = nullptr;
@@ -290,6 +298,8 @@
// copy-on-write mapping that can incorporate changes from a shared mapping
// owned by another process.
void TestFromSharedToPrivate() {
+ // Zygote JIT memory only works on kernels that don't segfault on flush.
+ TEST_DISABLED_FOR_KERNELS_WITH_CACHE_SEGFAULT();
// This test is only for memfd with future write sealing support:
// 1) ashmem with PROT_READ doesn't permit mapping MAP_PRIVATE | PROT_WRITE
// 2) ashmem mapped MAP_PRIVATE discards the contents already written.