Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mpk: maintain mapping of pkey ID to stripe ID #7353

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions crates/runtime/src/mpk/enabled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ pub fn keys() -> &'static [ProtectionKey] {
if is_supported() {
while let Ok(key_id) = sys::pkey_alloc(0, 0) {
debug_assert!(key_id < 16);
// UNSAFETY: here we unsafely assume that the system-allocated pkey
// will exist forever.
let pkey = ProtectionKey(key_id);
debug_assert_eq!(pkey.as_stripe(), allocated.len());
allocated.push(pkey);
// UNSAFETY: here we unsafely assume that the system-allocated
// pkey will exist forever.
allocated.push(ProtectionKey {
id: key_id,
stripe: allocated.len().try_into().unwrap(),
});
}
}
allocated
Expand Down Expand Up @@ -58,7 +59,10 @@ pub fn allow(mask: ProtectionMask) {
/// [`ProtectionMask`]; any accesses to unmarked pages result in a fault
/// - drop the key
#[derive(Clone, Copy, Debug)]
pub struct ProtectionKey(u32);
pub struct ProtectionKey {
id: u32,
stripe: u32,
}

impl ProtectionKey {
/// Mark a page as protected by this [`ProtectionKey`].
Expand All @@ -75,7 +79,7 @@ impl ProtectionKey {
let addr = region.as_mut_ptr() as usize;
let len = region.len();
let prot = sys::PROT_READ | sys::PROT_WRITE;
sys::pkey_mprotect(addr, len, prot, self.0).with_context(|| {
sys::pkey_mprotect(addr, len, prot, self.id).with_context(|| {
format!(
"failed to mark region with pkey (addr = {addr:#x}, len = {len}, prot = {prot:#b})"
)
Expand All @@ -87,8 +91,7 @@ impl ProtectionKey {
///
/// This function assumes that the kernel has allocated key 0 for itself.
pub fn as_stripe(&self) -> usize {
debug_assert!(self.0 != 0);
self.0 as usize - 1
self.stripe as usize
}
}

Expand Down Expand Up @@ -117,7 +120,7 @@ impl ProtectionMask {
/// Include `pkey` as another allowed protection key in the mask.
#[inline]
pub fn or(self, pkey: ProtectionKey) -> Self {
let mask = pkru::DISABLE_ACCESS ^ 0b11 << (pkey.0 * 2);
let mask = pkru::DISABLE_ACCESS ^ 0b11 << (pkey.id * 2);
Self(self.0 & mask)
}
}
Expand Down Expand Up @@ -178,13 +181,13 @@ mod tests {
allow(ProtectionMask::all());
assert_eq!(0, pkru::read());

allow(ProtectionMask::all().or(ProtectionKey(5)));
allow(ProtectionMask::all().or(ProtectionKey { id: 5, stripe: 0 }));
assert_eq!(0, pkru::read());

allow(ProtectionMask::zero());
assert_eq!(0b11111111_11111111_11111111_11111100, pkru::read());

allow(ProtectionMask::zero().or(ProtectionKey(5)));
allow(ProtectionMask::zero().or(ProtectionKey { id: 5, stripe: 0 }));
assert_eq!(0b11111111_11111111_11110011_11111100, pkru::read());

// Reset the PKRU state to what we originally observed.
Expand Down
3 changes: 2 additions & 1 deletion crates/wasmtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2374,7 +2374,8 @@ impl PoolingAllocationConfig {
/// supported
/// - `disable`: never use MPK
///
/// By default this value is `disabled`, but may become `auto` in future releases.
/// By default this value is `disabled`, but may become `auto` in future
/// releases.
///
/// __WARNING__: this configuration options is still experimental--use at
/// your own risk! MPK uses kernel and CPU features to protect memory
Expand Down