Commit 29d7cca5 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[wasm] Move SetThreadWritable to the WasmCodeManager

Since PKU-based switching always switches the permissions for all wasm
code memory in the process, the method should not be on the
{NativeModule} or {WasmCodeAllocator}, but instead on the process-wide
{WasmCodeManager}.

R=jkummerow@chromium.org

Bug: v8:11974
Change-Id: I75a82e51401b2572977c134077e1669cf5077049
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3021382
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75694}
parent c8d60d7e
......@@ -5,6 +5,7 @@
#include "src/wasm/code-space-access.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-engine.h"
namespace v8 {
namespace internal {
......@@ -38,7 +39,7 @@ CodeSpaceWriteScope::CodeSpaceWriteScope(NativeModule* native_module)
: native_module_(native_module) {
DCHECK_NOT_NULL(native_module_);
if (FLAG_wasm_memory_protection_keys) {
bool success = native_module_->SetThreadWritable(true);
bool success = GetWasmCodeManager()->SetThreadWritable(true);
if (!success && FLAG_wasm_write_protect_code_memory) {
// Fallback to mprotect-based write protection (much slower).
success = native_module_->SetWritable(true);
......@@ -52,7 +53,7 @@ CodeSpaceWriteScope::CodeSpaceWriteScope(NativeModule* native_module)
CodeSpaceWriteScope::~CodeSpaceWriteScope() {
if (FLAG_wasm_memory_protection_keys) {
bool success = native_module_->SetThreadWritable(false);
bool success = GetWasmCodeManager()->SetThreadWritable(false);
if (!success && FLAG_wasm_write_protect_code_memory) {
// Fallback to mprotect-based write protection (much slower).
success = native_module_->SetWritable(false);
......
......@@ -767,26 +767,6 @@ bool WasmCodeAllocator::SetWritable(bool writable) {
return true;
}
bool WasmCodeAllocator::SetThreadWritable(bool writable) {
static thread_local int writable_nesting_level = 0;
if (writable) {
if (++writable_nesting_level > 1) return true;
} else {
DCHECK_GT(writable_nesting_level, 0);
if (--writable_nesting_level > 0) return true;
}
writable = writable_nesting_level > 0;
int key = GetWasmCodeManager()->memory_protection_key_;
MemoryProtectionKeyPermission permissions =
writable ? kNoRestrictions : kDisableWrite;
TRACE_HEAP("Setting memory protection key %d to writable: %d.\n", key,
writable);
return SetPermissionsForMemoryProtectionKey(key, permissions);
}
void WasmCodeAllocator::FreeCode(base::Vector<WasmCode* const> codes) {
// Zap code area and collect freed code regions.
DisjointAllocationPool freed_regions;
......@@ -1974,6 +1954,25 @@ size_t WasmCodeManager::EstimateNativeModuleMetaDataSize(
return wasm_module_estimate + native_module_estimate;
}
bool WasmCodeManager::SetThreadWritable(bool writable) {
static thread_local int writable_nesting_level = 0;
if (writable) {
if (++writable_nesting_level > 1) return true;
} else {
DCHECK_GT(writable_nesting_level, 0);
if (--writable_nesting_level > 0) return true;
}
writable = writable_nesting_level > 0;
MemoryProtectionKeyPermission permissions =
writable ? kNoRestrictions : kDisableWrite;
TRACE_HEAP("Setting memory protection key %d to writable: %d.\n",
memory_protection_key_, writable);
return SetPermissionsForMemoryProtectionKey(memory_protection_key_,
permissions);
}
std::shared_ptr<NativeModule> WasmCodeManager::NewNativeModule(
Isolate* isolate, const WasmFeatures& enabled, size_t code_size_estimate,
std::shared_ptr<const WasmModule> module) {
......
......@@ -513,12 +513,6 @@ class WasmCodeAllocator {
// Hold the {NativeModule}'s {allocation_mutex_} when calling this method.
V8_EXPORT_PRIVATE bool SetWritable(bool writable);
// Set this thread's permission of all owned code space to read-write or
// read-only (if {writable} is false). Uses memory protection keys.
// Returns true on success. Since the permission is thread-local, there is no
// requirement to hold any lock when calling this method.
bool SetThreadWritable(bool writable);
// Free memory pages of all given code objects. Used for wasm code GC.
// Hold the {NativeModule}'s {allocation_mutex_} when calling this method.
void FreeCode(base::Vector<WasmCode* const>);
......@@ -668,10 +662,6 @@ class V8_EXPORT_PRIVATE NativeModule final {
return code_allocator_.SetWritable(writable);
}
bool SetThreadWritable(bool writable) {
return code_allocator_.SetThreadWritable(writable);
}
// For cctests, where we build both WasmModule and the runtime objects
// on the fly, and bypass the instance builder pipeline.
void ReserveCodeTableForTesting(uint32_t max_functions);
......@@ -965,6 +955,12 @@ class V8_EXPORT_PRIVATE WasmCodeManager final {
// generated code. This data still be stored on the C++ heap.
static size_t EstimateNativeModuleMetaDataSize(const WasmModule* module);
// Set this thread's permission of all owned code space to read-write or
// read-only (if {writable} is false). Uses memory protection keys.
// Returns true on success. Since the permission is thread-local, there is no
// requirement to hold any lock when calling this method.
bool SetThreadWritable(bool writable);
private:
friend class WasmCodeAllocator;
friend class WasmEngine;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment