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§

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.

Handles guest memory policy hints/advices.

Creates backing shm for GuestMemory regions

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

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

Creates a GuestMemory from a collection of MemoryRegions.

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(())

Returns the guest addresses and sizes of the memory regions.

Returns the total size of memory in bytes.

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

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

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.

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.

Returns the size of the memory region in bytes.

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(())

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))
}

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(())

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))
}

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(|_| ())?;

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(|_| ())?;

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(|_| ())

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(|_| ())

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);

Reads data from a file descriptor and writes it to guest memory.

Arguments
  • guest_addr - Begin writing memory at this offset.
  • src - Read from src to memory.
  • count - Read count bytes from src to memory.
Examples
  • Read bytes from /dev/urandom
      let mut file = File::open(Path::new("/dev/urandom")).map_err(|_| ())?;
      let addr = GuestAddress(0x1010);
      gm.read_to_memory(addr, &mut file, 128).map_err(|_| ())?;
      let read_addr = addr.checked_add(8).ok_or(())?;
      let rand_val: u32 = gm.read_obj_from_addr(read_addr).map_err(|_| ())?;

Writes data from memory to a file descriptor.

Arguments
  • guest_addr - Begin reading memory from this offset.
  • dst - Write from memory to dst.
  • count - Read count bytes from memory to src.
Examples
  • Write 128 bytes to /dev/null
      let mut file = File::open(Path::new("/dev/null")).map_err(|_| ())?;
      let addr = GuestAddress(0x1010);
      gm.write_from_memory(addr, &mut file, 128).map_err(|_| ())?;

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_from_memory, 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(())

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(())

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

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

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.

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);

Copy all guest memory into w.

Assumes 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.

Restore the guest memory using the bytes from r.

Assumes 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§

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

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.
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.