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