Browse Source

Disable memory protection keys by default at compile time (#8813)

* Disable memory protection keys by default at compile time

This commit gates memory protection keys behind a new Cargo feature
which is disabled by default. Memory protection keys are already
disabled by default on all platforms and are only configured to possibly
work with Linux x64. When enabled, however, it unconditionally adds a
small amount of overhead to WebAssembly entries/exits even if the
feature is disabled at runtime for the same reason that the `call-hook`
feature adds overhead. With `call-hook` being disabled by default
in #8808 it seemed reasonable to additionally gate memory protection
keys to avoid needing to disable features in Wasmtime to get the best
performance wasm<->host calls.

* Enable Wasmtime feature for fuzzing
pull/6899/merge
Alex Crichton 5 months ago
committed by GitHub
parent
commit
0f48f939b9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      Cargo.toml
  2. 3
      crates/cli-flags/Cargo.toml
  3. 12
      crates/cli-flags/src/lib.rs
  4. 2
      crates/fuzzing/Cargo.toml
  5. 4
      crates/wasmtime/Cargo.toml
  6. 7
      crates/wasmtime/src/config.rs
  7. 7
      crates/wasmtime/src/lib.rs
  8. 3
      crates/wasmtime/src/runtime/vm/mpk/mod.rs

3
Cargo.toml

@ -82,7 +82,7 @@ rustix = { workspace = true, features = ["mm", "param", "process"] }
[dev-dependencies]
# depend again on wasmtime to activate its default features for tests
wasmtime = { workspace = true, features = ['default', 'winch', 'all-arch', 'call-hook'] }
wasmtime = { workspace = true, features = ['default', 'winch', 'all-arch', 'call-hook', 'memory-protection-keys'] }
env_logger = { workspace = true }
log = { workspace = true }
filecheck = { workspace = true }
@ -376,6 +376,7 @@ default = [
all-arch = ["wasmtime/all-arch"]
winch = ["wasmtime/winch"]
wmemcheck = ["wasmtime/wmemcheck"]
memory-protection-keys = ["wasmtime-cli-flags/memory-protection-keys"]
# This feature, when enabled, will statically compile out all logging statements
# throughout Wasmtime and its dependencies.

3
crates/cli-flags/Cargo.toml

@ -21,7 +21,7 @@ wasmtime = { workspace = true, features = ["gc"] }
humantime = { workspace = true }
[features]
pooling-allocator = []
pooling-allocator = ["wasmtime/pooling-allocator"]
component-model = ["wasmtime/component-model"]
cache = ["wasmtime/cache"]
parallel-compilation = ["wasmtime/parallel-compilation", "dep:rayon"]
@ -30,3 +30,4 @@ cranelift = ["wasmtime/cranelift"]
coredump = ["wasmtime/coredump"]
gc = ["wasmtime/gc"]
threads = ["wasmtime/threads"]
memory-protection-keys = ["wasmtime/memory-protection-keys"]

12
crates/cli-flags/src/lib.rs

@ -612,10 +612,14 @@ impl CommonOptions {
if let Some(limit) = self.opts.pooling_max_memory_size {
cfg.max_memory_size(limit);
}
if let Some(enable) = self.opts.memory_protection_keys {
if enable {
cfg.memory_protection_keys(wasmtime::MpkEnabled::Enable);
}
match_feature! {
["memory-protection-keys" : self.opts.memory_protection_keys]
enable => cfg.memory_protection_keys(if enable {
wasmtime::MpkEnabled::Enable
} else {
wasmtime::MpkEnabled::Disable
}),
_ => err,
}
config.allocation_strategy(wasmtime::InstanceAllocationStrategy::Pooling(cfg));
}

2
crates/fuzzing/Cargo.toml

@ -22,7 +22,7 @@ target-lexicon = { workspace = true }
tempfile = "3.3.0"
wasmparser = { workspace = true }
wasmprinter = { workspace = true }
wasmtime = { workspace = true, features = ['default', 'winch', 'gc'] }
wasmtime = { workspace = true, features = ['default', 'winch', 'gc', 'memory-protection-keys'] }
wasmtime-wast = { workspace = true }
wasm-encoder = { workspace = true }
wasm-smith = { workspace = true }

4
crates/wasmtime/Cargo.toml

@ -264,3 +264,7 @@ std = [
# logic around all entries/exits from WebAssembly. This has a slight performance
# cost for all host functions.
call-hook = []
# Enables support for "memory protection keys" which can be used in conjunction
# with the pooling allocator on x64 to compact linear memory allocations.
memory-protection-keys = ["pooling-allocator"]

7
crates/wasmtime/src/config.rs

@ -28,8 +28,6 @@ use crate::stack::{StackCreator, StackCreatorProxy};
#[cfg(feature = "async")]
use wasmtime_fiber::RuntimeFiberStackCreator;
#[cfg(feature = "pooling-allocator")]
use crate::runtime::vm::mpk;
#[cfg(feature = "pooling-allocator")]
pub use crate::runtime::vm::MpkEnabled;
#[cfg(all(feature = "incremental-cache", feature = "cranelift"))]
@ -2821,6 +2819,7 @@ impl PoolingAllocationConfig {
/// your own risk! MPK uses kernel and CPU features to protect memory
/// regions; you may observe segmentation faults if anything is
/// misconfigured.
#[cfg(feature = "memory-protection-keys")]
pub fn memory_protection_keys(&mut self, enable: MpkEnabled) -> &mut Self {
self.config.memory_protection_keys = enable;
self
@ -2838,6 +2837,7 @@ impl PoolingAllocationConfig {
/// engines will share the same set of allocated keys; this setting will
/// limit how many keys are allocated initially and thus available to all
/// other engines.
#[cfg(feature = "memory-protection-keys")]
pub fn max_memory_protection_keys(&mut self, max: usize) -> &mut Self {
self.config.max_memory_protection_keys = max;
self
@ -2849,8 +2849,9 @@ impl PoolingAllocationConfig {
/// same method that [`MpkEnabled::Auto`] does. See
/// [`PoolingAllocationConfig::memory_protection_keys`] for more
/// information.
#[cfg(feature = "memory-protection-keys")]
pub fn are_memory_protection_keys_available() -> bool {
mpk::is_supported()
crate::runtime::vm::mpk::is_supported()
}
/// The maximum number of concurrent GC heaps supported (default is `1000`).

7
crates/wasmtime/src/lib.rs

@ -259,6 +259,13 @@
//! entries/exits from WebAssembly and may want to be disabled by some
//! embedders.
//!
//! * `memory-protection-keys` - Disabled by default, this enables support for
//! the [`PoolingAllocationConfig::memory_protection_keys`] API. This feature
//! currently only works on x64 Linux and can enable compacting the virtual
//! memory allocation for linear memories in the pooling allocator. This comes
//! with the same overhead as the `call-hook` feature where entries/exits into
//! WebAssembly will have more overhead than before.
//!
//! More crate features can be found in the [manifest] of Wasmtime itself for
//! seeing what can be enabled and disabled.
//!

3
crates/wasmtime/src/runtime/vm/mpk/mod.rs

@ -33,8 +33,7 @@ cfg_if::cfg_if! {
if #[cfg(all(
target_arch = "x86_64",
target_os = "linux",
feature = "pooling-allocator",
feature = "std",
feature = "memory-protection-keys",
not(miri),
))] {
mod enabled;

Loading…
Cancel
Save