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:
Peter Huene
2021-03-04 14:01:42 -08:00
parent a464465e2f
commit ff840b3d3b
11 changed files with 484 additions and 500 deletions

View File

@@ -1,27 +1,64 @@
use crate::Mmap;
use anyhow::{anyhow, Result};
use anyhow::{bail, Context, Result};
pub unsafe fn make_accessible(addr: *mut u8, len: usize) -> bool {
region::protect(addr, len, region::Protection::READ_WRITE).is_ok()
}
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
if len == 0 {
return Ok(());
}
pub unsafe fn decommit(addr: *mut u8, len: usize) {
assert_eq!(
if unsafe {
libc::mmap(
addr as _,
len,
libc::PROT_NONE,
if protect {
libc::PROT_NONE
} else {
libc::PROT_READ | libc::PROT_WRITE
},
libc::MAP_PRIVATE | libc::MAP_ANON | libc::MAP_FIXED,
-1,
0,
) as *mut u8,
addr,
"mmap failed to remap pages: {}",
std::io::Error::last_os_error()
);
) as *mut u8
} != addr
{
bail!(
"mmap failed to remap pages: {}",
std::io::Error::last_os_error()
);
}
Ok(())
}
pub fn create_memory_map(accessible_size: usize, mapping_size: usize) -> Result<Mmap> {
Mmap::accessible_reserved(accessible_size, mapping_size)
.map_err(|e| anyhow!("failed to allocate pool memory: {}", e))
pub fn commit_memory_pages(addr: *mut u8, len: usize) -> Result<()> {
if len == 0 {
return Ok(());
}
// Just change the protection level to READ|WRITE
unsafe {
region::protect(addr, len, region::Protection::READ_WRITE)
.context("failed to make linear memory pages read/write")
}
}
pub fn decommit_memory_pages(addr: *mut u8, len: usize) -> Result<()> {
decommit(addr, len, true)
}
pub fn commit_table_pages(_addr: *mut u8, _len: usize) -> Result<()> {
// A no-op as table pages remain READ|WRITE
Ok(())
}
pub fn decommit_table_pages(addr: *mut u8, len: usize) -> Result<()> {
decommit(addr, len, false)
}
pub fn commit_stack_pages(_addr: *mut u8, _len: usize) -> Result<()> {
// A no-op as stack pages remain READ|WRITE
Ok(())
}
pub fn decommit_stack_pages(addr: *mut u8, len: usize) -> Result<()> {
decommit(addr, len, false)
}