wasmtime_runtime/mpk/mod.rs
1//! Memory Protection Keys (MPK) implementation for use in striped memory
2//! allocation.
3//!
4//! MPK is an x86 feature available on relatively recent versions of Intel and
5//! AMD CPUs. In Linux, this feature is named `pku` (protection keys userspace)
6//! and consists of three new system calls: `pkey_alloc`, `pkey_free`, and
7//! `pkey_mprotect` (see the [Linux documentation]). This crate provides an
8//! abstraction, [`ProtectionKey`], that the [pooling allocator] applies to
9//! contiguous memory allocations, allowing it to avoid guard pages in some
10//! cases and more efficiently use memory. This technique was first presented in
11//! a 2022 paper: [Segue and ColorGuard: Optimizing SFI Performance and
12//! Scalability on Modern x86][colorguard].
13//!
14//! [pooling allocator]: crate::PoolingInstanceAllocator
15//! [Linux documentation]:
16//! https://www.kernel.org/doc/html/latest/core-api/protection-keys.html
17//! [colorguard]: https://plas2022.github.io/files/pdf/SegueColorGuard.pdf
18//!
19//! On x86_64 Linux systems, this module implements the various parts necessary
20//! to use MPK in Wasmtime:
21//! - [`is_supported`] indicates whether the feature is available at runtime
22//! - [`ProtectionKey`] provides access to the kernel-allocated protection keys
23//! (see [`keys`])
24//! - [`allow`] sets the CPU state to prevent access to regions outside the
25//! [`ProtectionMask`]
26//! - the `sys` module bridges the gap to Linux's `pkey_*` system calls
27//! - the `pkru` module controls the x86 `PKRU` register (and other CPU state)
28//!
29//! On any other kind of machine, this module exposes noop implementations of
30//! the public interface.
31
32cfg_if::cfg_if! {
33 if #[cfg(all(target_arch = "x86_64", target_os = "linux", not(miri)))] {
34 mod enabled;
35 mod pkru;
36 mod sys;
37 pub use enabled::{allow, current_mask, is_supported, keys, ProtectionKey, ProtectionMask};
38 } else {
39 mod disabled;
40 pub use disabled::{allow, current_mask, is_supported, keys, ProtectionKey, ProtectionMask};
41 }
42}
43
44/// Describe the tri-state configuration of memory protection keys (MPK).
45#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
46pub enum MpkEnabled {
47 /// Use MPK if supported by the current system; fall back to guard regions
48 /// otherwise.
49 Auto,
50 /// Use MPK or fail if not supported.
51 Enable,
52 /// Do not use MPK.
53 Disable,
54}