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::runtime::vm::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 32 cfg_if::cfg_if! { 33 if #[cfg(all( 34 target_arch = "x86_64", 35 target_os = "linux", 36 feature = "memory-protection-keys", 37 not(miri), 38 ))] { 39 mod enabled; 40 mod pkru; 41 mod sys; 42 pub use enabled::*; 43 } else { 44 mod disabled; 45 pub use disabled::*; 46 } 47 } 48