Skip to content
Merged
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
24 changes: 16 additions & 8 deletions src/volatile_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
//! doing with that hunk of memory.
//!
//! For the purposes of maintaining safety, volatile memory has some rules of its own:
//!
//! 1. No references or slices to volatile memory (`&` or `&mut`).
//!
//! 2. Access should always been done with a volatile read or write.
//! The First rule is because having references of any kind to memory considered volatile would
//! violate pointer aliasing. The second is because unvolatile accesses are inherently undefined if
//! done concurrently without synchronization. With volatile access we know that the compiler has
//! not reordered or elided the access.
//!
//! The First rule is because having references of any kind to memory considered volatile would
//! violate pointer aliasing. The second is because unvolatile accesses are inherently undefined if
//! done concurrently without synchronization. With volatile access we know that the compiler has
//! not reordered or elided the access.

use std::cmp::min;
use std::io::{self, Read, Write};
Expand Down Expand Up @@ -85,7 +88,7 @@ pub type Result<T> = result::Result<T, Error>;
/// # use vm_memory::volatile_memory::compute_offset;
/// #
/// assert_eq!(108, compute_offset(100, 8).unwrap());
/// assert!(compute_offset(std::usize::MAX, 6).is_err());
/// assert!(compute_offset(usize::MAX, 6).is_err());
/// ```
pub fn compute_offset(base: usize, offset: usize) -> Result<usize> {
match base.checked_add(offset) {
Expand Down Expand Up @@ -315,9 +318,14 @@ pub struct PtrGuard {
#[allow(clippy::len_without_is_empty)]
impl PtrGuard {
#[allow(unused_variables)]
fn new(mmap: Option<&MmapInfo>, addr: *mut u8, prot: i32, len: usize) -> Self {
fn new(mmap: Option<&MmapInfo>, addr: *mut u8, write: bool, len: usize) -> Self {
#[cfg(all(feature = "xen", unix))]
let (addr, _slice) = {
let prot = if write {
libc::PROT_WRITE
} else {
libc::PROT_READ
};
let slice = MmapInfo::mmap(mmap, addr, prot, len);
(slice.addr(), slice)
};
Expand All @@ -332,7 +340,7 @@ impl PtrGuard {
}

fn read(mmap: Option<&MmapInfo>, addr: *mut u8, len: usize) -> Self {
Self::new(mmap, addr, libc::PROT_READ, len)
Self::new(mmap, addr, false, len)
}

/// Returns a non-mutable pointer to the beginning of the slice.
Expand All @@ -353,7 +361,7 @@ pub struct PtrGuardMut(PtrGuard);
#[allow(clippy::len_without_is_empty)]
impl PtrGuardMut {
fn write(mmap: Option<&MmapInfo>, addr: *mut u8, len: usize) -> Self {
Self(PtrGuard::new(mmap, addr, libc::PROT_WRITE, len))
Self(PtrGuard::new(mmap, addr, true, len))
}

/// Returns a mutable pointer to the beginning of the slice. Mutable accesses performed
Expand Down