From 58380f1019f670349be7596d1f67854f007ae602 Mon Sep 17 00:00:00 2001 From: Lars T Hansen Date: Thu, 14 Mar 2019 17:22:50 +0100 Subject: [PATCH] Bug 1529933 - Execute a fence before mprotect. r=luke Differential Revision: https://phabricator.services.mozilla.com/D23527 --HG-- extra : rebase_source : 308870f382b88afbf1e8671676873723c93ee023 --- js/src/jit/ProcessExecutableMemory.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/js/src/jit/ProcessExecutableMemory.cpp b/js/src/jit/ProcessExecutableMemory.cpp index da14999dd85e..d395ccf51cab 100644 --- a/js/src/jit/ProcessExecutableMemory.cpp +++ b/js/src/jit/ProcessExecutableMemory.cpp @@ -23,6 +23,7 @@ #ifdef JS_CODEGEN_ARM64 # include "jit/arm64/vixl/Cpu-vixl.h" #endif +#include "jit/AtomicOperations.h" #include "threading/LockGuard.h" #include "threading/Mutex.h" #include "util/Windows.h" @@ -725,6 +726,19 @@ bool js::jit::ReprotectRegion(void* start, size_t size, execMemory.assertValidAddress(pageStart, size); + // On weak memory systems, make sure new code is visible on all cores before + // addresses of the code are made public. Now is the latest moment in time + // when we can do that, and we're assuming that every other thread that has + // written into the memory that is being reprotected here has synchronized + // with this thread in such a way that the memory writes have become visible + // and we therefore only need to execute the fence once here. See bug 1529933 + // for a longer discussion of why this is both necessary and sufficient. + // + // We use the C++ fence here -- and not AtomicOperations::fenceSeqCst() -- + // primarily because ReprotectRegion will be called while we construct our own + // jitted atomics. But the C++ fence is sufficient and correct, too. + std::atomic_thread_fence(std::memory_order_seq_cst); + #ifdef XP_WIN DWORD oldProtect; DWORD flags = ProtectionSettingToFlags(protection);