Skip to content

Commit

Permalink
Disable memory protection keys by default at compile time (#8813)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
alexcrichton authored Jun 14, 2024
1 parent b7fd095 commit 0f48f93
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 12 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion crates/cli-flags/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand All @@ -30,3 +30,4 @@ cranelift = ["wasmtime/cranelift"]
coredump = ["wasmtime/coredump"]
gc = ["wasmtime/gc"]
threads = ["wasmtime/threads"]
memory-protection-keys = ["wasmtime/memory-protection-keys"]
12 changes: 8 additions & 4 deletions crates/cli-flags/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion crates/fuzzing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
4 changes: 4 additions & 0 deletions crates/wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 4 additions & 3 deletions crates/wasmtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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`).
Expand Down
7 changes: 7 additions & 0 deletions crates/wasmtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//!
Expand Down
3 changes: 1 addition & 2 deletions crates/wasmtime/src/runtime/vm/mpk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 0f48f93

Please sign in to comment.