More PR feedback changes.
* More use of `anyhow`. * Change `make_accessible` into `protect_linear_memory` to better demonstrate what it is used for; this will make the uffd implementation make a little more sense. * Remove `create_memory_map` in favor of just creating the `Mmap` instances in the pooling allocator. This also removes the need for `MAP_NORESERVE` in the uffd implementation. * Moar comments. * Remove `BasePointerIterator` in favor of `impl Iterator`. * The uffd implementation now only monitors linear memory pages and will only receive faults on pages that could potentially be accessible and never on a statically known guard page. * Stop allocating memory or table pools if the maximum limit of the memory or table is 0.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
//! Low-level abstraction for allocating and managing zero-filled pages
|
||||
//! of memory.
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use more_asserts::assert_le;
|
||||
use more_asserts::assert_lt;
|
||||
use std::io;
|
||||
@@ -38,7 +39,7 @@ impl Mmap {
|
||||
}
|
||||
|
||||
/// Create a new `Mmap` pointing to at least `size` bytes of page-aligned accessible memory.
|
||||
pub fn with_at_least(size: usize) -> Result<Self, String> {
|
||||
pub fn with_at_least(size: usize) -> Result<Self> {
|
||||
let page_size = region::page::size();
|
||||
let rounded_size = round_up_to_page_size(size, page_size);
|
||||
Self::accessible_reserved(rounded_size, rounded_size)
|
||||
@@ -48,10 +49,7 @@ impl Mmap {
|
||||
/// within a reserved mapping of `mapping_size` bytes. `accessible_size` and `mapping_size`
|
||||
/// must be native page-size multiples.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn accessible_reserved(
|
||||
accessible_size: usize,
|
||||
mapping_size: usize,
|
||||
) -> Result<Self, String> {
|
||||
pub fn accessible_reserved(accessible_size: usize, mapping_size: usize) -> Result<Self> {
|
||||
let page_size = region::page::size();
|
||||
assert_le!(accessible_size, mapping_size);
|
||||
assert_eq!(mapping_size & (page_size - 1), 0);
|
||||
@@ -76,7 +74,7 @@ impl Mmap {
|
||||
)
|
||||
};
|
||||
if ptr as isize == -1_isize {
|
||||
return Err(io::Error::last_os_error().to_string());
|
||||
bail!("mmap failed: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
Self {
|
||||
@@ -96,7 +94,7 @@ impl Mmap {
|
||||
)
|
||||
};
|
||||
if ptr as isize == -1_isize {
|
||||
return Err(io::Error::last_os_error().to_string());
|
||||
bail!("mmap failed: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let mut result = Self {
|
||||
@@ -117,10 +115,7 @@ impl Mmap {
|
||||
/// within a reserved mapping of `mapping_size` bytes. `accessible_size` and `mapping_size`
|
||||
/// must be native page-size multiples.
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn accessible_reserved(
|
||||
accessible_size: usize,
|
||||
mapping_size: usize,
|
||||
) -> Result<Self, String> {
|
||||
pub fn accessible_reserved(accessible_size: usize, mapping_size: usize) -> Result<Self> {
|
||||
use winapi::um::memoryapi::VirtualAlloc;
|
||||
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_NOACCESS, PAGE_READWRITE};
|
||||
|
||||
@@ -144,7 +139,7 @@ impl Mmap {
|
||||
)
|
||||
};
|
||||
if ptr.is_null() {
|
||||
return Err(io::Error::last_os_error().to_string());
|
||||
bail!("VirtualAlloc failed: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
Self {
|
||||
@@ -156,7 +151,7 @@ impl Mmap {
|
||||
let ptr =
|
||||
unsafe { VirtualAlloc(ptr::null_mut(), mapping_size, MEM_RESERVE, PAGE_NOACCESS) };
|
||||
if ptr.is_null() {
|
||||
return Err(io::Error::last_os_error().to_string());
|
||||
bail!("VirtualAlloc failed: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let mut result = Self {
|
||||
@@ -177,7 +172,7 @@ impl Mmap {
|
||||
/// `start` and `len` must be native page-size multiples and describe a range within
|
||||
/// `self`'s reserved memory.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<(), String> {
|
||||
pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<()> {
|
||||
let page_size = region::page::size();
|
||||
assert_eq!(start & (page_size - 1), 0);
|
||||
assert_eq!(len & (page_size - 1), 0);
|
||||
@@ -186,15 +181,18 @@ impl Mmap {
|
||||
|
||||
// Commit the accessible size.
|
||||
let ptr = self.ptr as *const u8;
|
||||
unsafe { region::protect(ptr.add(start), len, region::Protection::READ_WRITE) }
|
||||
.map_err(|e| e.to_string())
|
||||
unsafe {
|
||||
region::protect(ptr.add(start), len, region::Protection::READ_WRITE)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Make the memory starting at `start` and extending for `len` bytes accessible.
|
||||
/// `start` and `len` must be native page-size multiples and describe a range within
|
||||
/// `self`'s reserved memory.
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<(), String> {
|
||||
pub fn make_accessible(&mut self, start: usize, len: usize) -> Result<()> {
|
||||
use winapi::ctypes::c_void;
|
||||
use winapi::um::memoryapi::VirtualAlloc;
|
||||
use winapi::um::winnt::{MEM_COMMIT, PAGE_READWRITE};
|
||||
@@ -216,7 +214,7 @@ impl Mmap {
|
||||
}
|
||||
.is_null()
|
||||
{
|
||||
return Err(io::Error::last_os_error().to_string());
|
||||
bail!("VirtualAlloc failed: {}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user