pub struct GuestMemory {
    regions: Arc<[MemoryRegion]>,
}
Expand description

Tracks memory regions and where they are mapped in the guest, along with shm descriptors of the underlying memory regions.

Fields§

§regions: Arc<[MemoryRegion]>

Implementations§

source§

impl GuestMemory

source

pub fn remove_range(&self, addr: GuestAddress, count: u64) -> Result<()>

Madvise away the address range in the host that is associated with the given guest range.

This feature is only available on Unix, where a MemoryMapping can remove a mapped range.

source

pub fn set_memory_policy(&self, mem_policy: MemoryPolicy)

Handles guest memory policy hints/advices.

source

pub fn use_dontfork(&self) -> Result<()>

source§

impl GuestMemory

source

fn create_shm( ranges: &[(GuestAddress, u64, MemoryRegionOptions)] ) -> Result<SharedMemory>

Creates backing shm for GuestMemory regions

source

pub fn new_with_options( ranges: &[(GuestAddress, u64, MemoryRegionOptions)] ) -> Result<GuestMemory>

Creates a container for guest memory regions. Valid memory regions are specified as a Vec of (Address, Size, MemoryRegionOptions)

source

pub fn new(ranges: &[(GuestAddress, u64)]) -> Result<GuestMemory>

Creates a container for guest memory regions. Valid memory regions are specified as a Vec of (Address, Size) tuples sorted by Address.

source

pub fn from_regions(regions: Vec<MemoryRegion>) -> Result<Self>

Creates a GuestMemory from a collection of MemoryRegions.

source

pub fn end_addr(&self) -> GuestAddress

Returns the end address of memory.

§Examples
    let start_addr = GuestAddress(0x1000);
    let mut gm = GuestMemory::new(&vec![(start_addr, 0x400)]).map_err(|_| ())?;
    assert_eq!(start_addr.checked_add(0x400), Some(gm.end_addr()));
    Ok(())
source

pub fn guest_memory_regions(&self) -> Vec<(GuestAddress, usize)>

Returns the guest addresses and sizes of the memory regions.

source

pub fn memory_size(&self) -> u64

Returns the total size of memory in bytes.

source

pub fn address_in_range(&self, addr: GuestAddress) -> bool

Returns true if the given address is within the memory range available to the guest.

source

pub fn range_overlap(&self, start: GuestAddress, end: GuestAddress) -> bool

Returns true if the given range (start, end) is overlap with the memory range available to the guest.

source

pub fn checked_offset( &self, addr: GuestAddress, offset: u64 ) -> Option<GuestAddress>

Returns an address addr + offset if it’s in range.

This function doesn’t care whether a region [addr, addr + offset) is in range or not. To guarantee it’s a valid range, use is_valid_range() instead.

source

pub fn is_valid_range(&self, start: GuestAddress, length: u64) -> bool

Returns true if the given range [start, start + length) is a valid contiguous memory range available to the guest and it’s backed by a single underlying memory region.

source

pub fn num_regions(&self) -> u64

Returns the size of the memory region in bytes.

source

pub fn regions(&self) -> impl Iterator<Item = MemoryRegionInformation<'_>>

source

pub fn write_at_addr( &self, buf: &[u8], guest_addr: GuestAddress ) -> Result<usize>

Writes a slice to guest memory at the specified guest address. Returns the number of bytes written. The number of bytes written can be less than the length of the slice if there isn’t enough room in the memory region.

§Examples
  • Write a slice at guestaddress 0x200.
    let res = gm.write_at_addr(&[1,2,3,4,5], GuestAddress(0x200)).map_err(|_| ())?;
    assert_eq!(5, res);
    Ok(())
source

pub fn write_all_at_addr( &self, buf: &[u8], guest_addr: GuestAddress ) -> Result<()>

Writes the entire contents of a slice to guest memory at the specified guest address.

Returns an error if there isn’t enough room in the memory region to complete the entire write. Part of the data may have been written nevertheless.

§Examples
use vm_memory::{guest_memory, GuestAddress, GuestMemory};

fn test_write_all() -> guest_memory::Result<()> {
    let ranges = &[(GuestAddress(0x1000), 0x400)];
    let gm = GuestMemory::new(ranges)?;
    gm.write_all_at_addr(b"zyxwvut", GuestAddress(0x1200))
}
source

pub fn read_at_addr( &self, buf: &mut [u8], guest_addr: GuestAddress ) -> Result<usize>

Reads to a slice from guest memory at the specified guest address. Returns the number of bytes read. The number of bytes read can be less than the length of the slice if there isn’t enough room in the memory region.

§Examples
  • Read a slice of length 16 at guestaddress 0x200.
    let buf = &mut [0u8; 16];
    let res = gm.read_at_addr(buf, GuestAddress(0x200)).map_err(|_| ())?;
    assert_eq!(16, res);
    Ok(())
source

pub fn read_exact_at_addr( &self, buf: &mut [u8], guest_addr: GuestAddress ) -> Result<()>

Reads from guest memory at the specified address to fill the entire buffer.

Returns an error if there isn’t enough room in the memory region to fill the entire buffer. Part of the buffer may have been filled nevertheless.

§Examples
use vm_memory::{guest_memory, GuestAddress, GuestMemory};

fn test_read_exact() -> guest_memory::Result<()> {
    let ranges = &[(GuestAddress(0x1000), 0x400)];
    let gm = GuestMemory::new(ranges)?;
    let mut buffer = [0u8; 0x200];
    gm.read_exact_at_addr(&mut buffer, GuestAddress(0x1200))
}
source

pub fn read_obj_from_addr<T: FromBytes>( &self, guest_addr: GuestAddress ) -> Result<T>

Reads an object from guest memory at the given guest address.

§Examples
  • Read a u64 from two areas of guest memory backed by separate mappings.
      let num1: u64 = gm.read_obj_from_addr(GuestAddress(32)).map_err(|_| ())?;
      let num2: u64 = gm.read_obj_from_addr(GuestAddress(0x400+32)).map_err(|_| ())?;
source

pub fn read_obj_from_addr_volatile<T: FromBytes>( &self, guest_addr: GuestAddress ) -> Result<T>

Reads an object from guest memory at the given guest address. Reading from a volatile area isn’t strictly safe as it could change mid-read. However, as long as the type T is plain old data and can handle random initialization, everything will be OK.

The read operation will be volatile, i.e. it will not be reordered by the compiler and is suitable for I/O, but must be aligned. When reading from regular memory, prefer GuestMemory::read_obj_from_addr.

§Examples
  • Read a u64 from two areas of guest memory backed by separate mappings.
      let num1: u64 = gm.read_obj_from_addr_volatile(GuestAddress(32)).map_err(|_| ())?;
      let num2: u64 = gm.read_obj_from_addr_volatile(GuestAddress(0x400+32)).map_err(|_| ())?;
source

pub fn write_obj_at_addr<T: AsBytes>( &self, val: T, guest_addr: GuestAddress ) -> Result<()>

Writes an object to the memory region at the specified guest address. Returns Ok(()) if the object fits, or Err if it extends past the end.

§Examples
  • Write a u64 at guest address 0x1100.
    gm.write_obj_at_addr(55u64, GuestAddress(0x1100))
        .map_err(|_| ())
source

pub fn write_obj_at_addr_volatile<T: AsBytes>( &self, val: T, guest_addr: GuestAddress ) -> Result<()>

Writes an object to the memory region at the specified guest address. Returns Ok(()) if the object fits, or Err if it extends past the end.

The write operation will be volatile, i.e. it will not be reordered by the compiler and is suitable for I/O, but must be aligned. When writing to regular memory, prefer GuestMemory::write_obj_at_addr.

§Examples
  • Write a u64 at guest address 0x1100.
    gm.write_obj_at_addr_volatile(55u64, GuestAddress(0x1100))
        .map_err(|_| ())
source

pub fn get_slice_at_addr( &self, addr: GuestAddress, len: usize ) -> Result<VolatileSlice<'_>>

Returns a VolatileSlice of len bytes starting at addr. Returns an error if the slice is not a subset of this GuestMemory.

§Examples
  • Write 99 to 30 bytes starting at guest address 0x1010.
    let vslice = gm.get_slice_at_addr(GuestAddress(0x1010), 30)?;
    vslice.write_bytes(99);
source

pub fn get_host_address(&self, guest_addr: GuestAddress) -> Result<*const u8>

Convert a GuestAddress into a pointer in the address space of this process. This should only be necessary for giving addresses to the kernel, as with vhost ioctls. Normal reads/writes to guest memory should be done through write_obj_at_addr, read_obj_from_addr, etc.

§Arguments
  • guest_addr - Guest address to convert.
§Examples
    let start_addr = GuestAddress(0x1000);
    let mut gm = GuestMemory::new(&vec![(start_addr, 0x500)]).map_err(|_| ())?;
    let addr = gm.get_host_address(GuestAddress(0x1200)).unwrap();
    println!("Host address is {:p}", addr);
    Ok(())
source

pub fn get_host_address_range( &self, guest_addr: GuestAddress, size: usize ) -> Result<*const u8>

Convert a GuestAddress into a pointer in the address space of this process, and verify that the provided size define a valid range within a single memory region. Similar to get_host_address(), this should only be used for giving addresses to the kernel.

§Arguments
  • guest_addr - Guest address to convert.
  • size - Size of the address range to be converted.
§Examples
    let start_addr = GuestAddress(0x1000);
    let mut gm = GuestMemory::new(&vec![(start_addr, 0x500)]).map_err(|_| ())?;
    let addr = gm.get_host_address_range(GuestAddress(0x1200), 0x200).unwrap();
    println!("Host address is {:p}", addr);
    Ok(())
source

pub fn shm_region( &self, guest_addr: GuestAddress ) -> Result<&(dyn AsRawDescriptor + Send + Sync)>

Returns a reference to the region that backs the given address.

source

pub fn offset_region( &self, offset: u64 ) -> Result<&(dyn AsRawDescriptor + Send + Sync)>

Returns the region that contains the memory at offset from the base of guest memory.

source

pub fn find_region( &self, guest_addr: GuestAddress ) -> Result<(&MemoryMapping, usize, u64)>

Loops over all guest memory regions of self, and returns the target region that contains guest_addr. On success, this function returns a tuple with the following fields:

(i) the memory mapping associated with the target region. (ii) the relative offset from the start of the target region to guest_addr. (iii) the absolute offset from the start of the memory mapping to the target region.

If no target region is found, an error is returned.

source

pub fn offset_from_base(&self, guest_addr: GuestAddress) -> Result<u64>

Convert a GuestAddress into an offset within the associated shm region.

Due to potential gaps within GuestMemory, it is helpful to know the offset within the shm where a given address is found. This offset can then be passed to another process mapping the shm to read data starting at that address.

§Arguments
  • guest_addr - Guest address to convert.
§Examples
let addr_a = GuestAddress(0x10000);
let addr_b = GuestAddress(0x80000);
let mut gm = GuestMemory::new(&vec![
    (addr_a, 0x20000),
    (addr_b, 0x30000)]).expect("failed to create GuestMemory");
let offset = gm.offset_from_base(GuestAddress(0x95000))
               .expect("failed to get offset");
assert_eq!(offset, 0x35000);
source

pub unsafe fn snapshot<T: Write>( &self, w: &mut T, compress: bool ) -> Result<Value>

Copy all guest memory into w.

§Safety

Must have exclusive access to the guest memory for the duration of the call (e.g. all vCPUs and devices must be stopped).

Returns a JSON object that contains metadata about the underlying memory regions to allow validation checks at restore time.

source

pub unsafe fn restore<T: Read>(&self, metadata: Value, r: &mut T) -> Result<()>

Restore the guest memory using the bytes from r.

§Safety

Must have exclusive access to the guest memory for the duration of the call (e.g. all vCPUs and devices must be stopped).

Returns an error if metadata doesn’t match the configuration of the GuestMemory or if r doesn’t produce exactly as many bytes as needed.

Trait Implementations§

source§

impl AsRawDescriptors for GuestMemory

source§

fn as_raw_descriptors(&self) -> Vec<RawDescriptor>

USE WITH CAUTION, the descriptors returned here are not necessarily files!

source§

impl BackingMemory for GuestMemory

source§

fn get_volatile_slice(&self, mem_range: MemRegion) -> Result<VolatileSlice<'_>>

Returns VolatileSlice pointing to the backing memory. This is most commonly unsafe. To implement this safely the implementor must guarantee that the backing memory can be modified out of band without affecting safety guarantees.
source§

impl Clone for GuestMemory

source§

fn clone(&self) -> GuestMemory

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for GuestMemory

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.