pub trait GuestMemory {
    type R: GuestMemoryRegion;
    type I: for<'a> GuestMemoryIterator<'a, Self::R>;

Show 19 methods // Required methods fn num_regions(&self) -> usize; fn find_region(&self, addr: GuestAddress) -> Option<&Self::R>; fn iter(&self) -> <Self::I as GuestMemoryIterator<'_, Self::R>>::Iter; // Provided methods fn with_regions<F, E>(&self, cb: F) -> Result<(), E> where F: Fn(usize, &Self::R) -> Result<(), E> { ... } fn with_regions_mut<F, E>(&self, cb: F) -> Result<(), E> where F: FnMut(usize, &Self::R) -> Result<(), E> { ... } fn map_and_fold<F, G, T>(&self, init: T, mapf: F, foldf: G) -> T where F: Fn((usize, &Self::R)) -> T, G: Fn(T, T) -> T { ... } fn last_addr(&self) -> GuestAddress { ... } fn to_region_addr( &self, addr: GuestAddress ) -> Option<(&Self::R, MemoryRegionAddress)> { ... } fn address_in_range(&self, addr: GuestAddress) -> bool { ... } fn check_address(&self, addr: GuestAddress) -> Option<GuestAddress> { ... } fn check_range(&self, base: GuestAddress, len: usize) -> bool { ... } fn checked_offset( &self, base: GuestAddress, offset: usize ) -> Option<GuestAddress> { ... } fn try_access<F>( &self, count: usize, addr: GuestAddress, f: F ) -> Result<usize> where F: FnMut(usize, usize, MemoryRegionAddress, &Self::R) -> Result<usize> { ... } fn read_volatile_from<F>( &self, addr: GuestAddress, src: &mut F, count: usize ) -> Result<usize> where F: ReadVolatile { ... } fn write_volatile_to<F>( &self, addr: GuestAddress, dst: &mut F, count: usize ) -> Result<usize> where F: WriteVolatile { ... } fn read_exact_volatile_from<F>( &self, addr: GuestAddress, src: &mut F, count: usize ) -> Result<()> where F: ReadVolatile { ... } fn write_all_volatile_to<F>( &self, addr: GuestAddress, dst: &mut F, count: usize ) -> Result<()> where F: WriteVolatile { ... } fn get_host_address(&self, addr: GuestAddress) -> Result<*mut u8> { ... } fn get_slice( &self, addr: GuestAddress, count: usize ) -> Result<VolatileSlice<'_, MS<'_, Self>>> { ... }
}
Expand description

GuestMemory represents a container for an immutable collection of GuestMemoryRegion objects. GuestMemory provides the Bytes<GuestAddress> trait to hide the details of accessing guest memory by physical address. Interior mutability is not allowed for implementations of GuestMemory so that they always provide a consistent view of the memory map.

The task of the GuestMemory trait are:

  • map a request address to a GuestMemoryRegion object and relay the request to it.
  • handle cases where an access request spanning two or more GuestMemoryRegion objects.

Required Associated Types§

source

type R: GuestMemoryRegion

Type of objects hosted by the address space.

source

type I: for<'a> GuestMemoryIterator<'a, Self::R>

Lifetime generic associated iterators. Usually this is just Self.

Required Methods§

source

fn num_regions(&self) -> usize

Returns the number of regions in the collection.

source

fn find_region(&self, addr: GuestAddress) -> Option<&Self::R>

Returns the region containing the specified address or None.

source

fn iter(&self) -> <Self::I as GuestMemoryIterator<'_, Self::R>>::Iter

Gets an iterator over the entries in the collection.

§Examples
  • Compute the total size of all memory mappings in KB by iterating over the memory regions and dividing their sizes to 1024, then summing up the values in an accumulator. (uses the backend-mmap feature)
let start_addr1 = GuestAddress(0x0);
let start_addr2 = GuestAddress(0x400);
let gm = GuestMemoryMmap::<()>::from_ranges(&vec![(start_addr1, 1024), (start_addr2, 2048)])
    .expect("Could not create guest memory");

let total_size = gm
    .iter()
    .map(|region| region.len() / 1024)
    .fold(0, |acc, size| acc + size);
assert_eq!(3, total_size)

Provided Methods§

source

fn with_regions<F, E>(&self, cb: F) -> Result<(), E>
where F: Fn(usize, &Self::R) -> Result<(), E>,

👎Deprecated since 0.6.0: Use .iter() instead

Perform the specified action on each region.

It only walks children of current region and does not step into sub regions.

source

fn with_regions_mut<F, E>(&self, cb: F) -> Result<(), E>
where F: FnMut(usize, &Self::R) -> Result<(), E>,

👎Deprecated since 0.6.0: Use .iter() instead

Perform the specified action on each region mutably.

It only walks children of current region and does not step into sub regions.

source

fn map_and_fold<F, G, T>(&self, init: T, mapf: F, foldf: G) -> T
where F: Fn((usize, &Self::R)) -> T, G: Fn(T, T) -> T,

👎Deprecated since 0.6.0: Use .iter() instead

Applies two functions, specified as callbacks, on the inner memory regions.

§Arguments
  • init - Starting value of the accumulator for the foldf function.
  • mapf - “Map” function, applied to all the inner memory regions. It returns an array of the same size as the memory regions array, containing the function’s results for each region.
  • foldf - “Fold” function, applied to the array returned by mapf. It acts as an operator, applying itself to the init value and to each subsequent elemnent in the array returned by mapf.
§Examples
  • Compute the total size of all memory mappings in KB by iterating over the memory regions and dividing their sizes to 1024, then summing up the values in an accumulator. (uses the backend-mmap feature)
let start_addr1 = GuestAddress(0x0);
let start_addr2 = GuestAddress(0x400);
let gm = GuestMemoryMmap::<()>::from_ranges(&vec![(start_addr1, 1024), (start_addr2, 2048)])
    .expect("Could not create guest memory");

let total_size = gm.map_and_fold(0, |(_, region)| region.len() / 1024, |acc, size| acc + size);
assert_eq!(3, total_size)
source

fn last_addr(&self) -> GuestAddress

Returns the maximum (inclusive) address managed by the GuestMemory.

§Examples (uses the backend-mmap feature)
let start_addr = GuestAddress(0x1000);
let mut gm = GuestMemoryMmap::<()>::from_ranges(&vec![(start_addr, 0x400)])
    .expect("Could not create guest memory");

assert_eq!(start_addr.checked_add(0x3ff), Some(gm.last_addr()));
source

fn to_region_addr( &self, addr: GuestAddress ) -> Option<(&Self::R, MemoryRegionAddress)>

Tries to convert an absolute address to a relative address within the corresponding region.

Returns None if addr isn’t present within the memory of the guest.

source

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

Returns true if the given address is present within the memory of the guest.

source

fn check_address(&self, addr: GuestAddress) -> Option<GuestAddress>

Returns the given address if it is present within the memory of the guest.

source

fn check_range(&self, base: GuestAddress, len: usize) -> bool

Check whether the range [base, base + len) is valid.

source

fn checked_offset( &self, base: GuestAddress, offset: usize ) -> Option<GuestAddress>

Returns the address plus the offset if it is present within the memory of the guest.

source

fn try_access<F>(&self, count: usize, addr: GuestAddress, f: F) -> Result<usize>
where F: FnMut(usize, usize, MemoryRegionAddress, &Self::R) -> Result<usize>,

Invokes callback f to handle data in the address range [addr, addr + count).

The address range [addr, addr + count) may span more than one GuestMemoryRegion object, or even have holes in it. So try_access() invokes the callback ‘f’ for each GuestMemoryRegion object involved and returns:

  • the error code returned by the callback ‘f’
  • the size of the already handled data when encountering the first hole
  • the size of the already handled data when the whole range has been handled
source

fn read_volatile_from<F>( &self, addr: GuestAddress, src: &mut F, count: usize ) -> Result<usize>
where F: ReadVolatile,

Reads up to count bytes from an object and writes them into guest memory at addr.

Returns the number of bytes written into guest memory.

§Arguments
  • addr - Begin writing at this address.
  • src - Copy from src into the container.
  • count - Copy count bytes from src into the container.
§Examples
  • Read bytes from /dev/urandom (uses the backend-mmap feature)
let mut file = File::open(Path::new("/dev/urandom")).expect("Could not open /dev/urandom");

gm.read_volatile_from(addr, &mut file, 128)
    .expect("Could not read from /dev/urandom into guest memory");

let read_addr = addr.checked_add(8).expect("Could not compute read address");
let rand_val: u32 = gm
    .read_obj(read_addr)
    .expect("Could not read u32 val from /dev/urandom");
source

fn write_volatile_to<F>( &self, addr: GuestAddress, dst: &mut F, count: usize ) -> Result<usize>
where F: WriteVolatile,

Reads up to count bytes from guest memory at addr and writes them it into an object.

Returns the number of bytes copied from guest memory.

§Arguments
  • addr - Begin reading from this address.
  • dst - Copy from guest memory to dst.
  • count - Copy count bytes from guest memory to dst.
source

fn read_exact_volatile_from<F>( &self, addr: GuestAddress, src: &mut F, count: usize ) -> Result<()>
where F: ReadVolatile,

Reads exactly count bytes from an object and writes them into guest memory at addr.

§Errors

Returns an error if count bytes couldn’t have been copied from src to guest memory. Part of the data may have been copied nevertheless.

§Arguments
  • addr - Begin writing at this address.
  • src - Copy from src into guest memory.
  • count - Copy exactly count bytes from src into guest memory.
source

fn write_all_volatile_to<F>( &self, addr: GuestAddress, dst: &mut F, count: usize ) -> Result<()>
where F: WriteVolatile,

Reads exactly count bytes from guest memory at addr and writes them into an object.

§Errors

Returns an error if count bytes couldn’t have been copied from guest memory to dst. Part of the data may have been copied nevertheless.

§Arguments
  • addr - Begin reading from this address.
  • dst - Copy from guest memory to dst.
  • count - Copy exactly count bytes from guest memory to dst.
source

fn get_host_address(&self, addr: GuestAddress) -> Result<*mut u8>

Get the host virtual address corresponding to the guest address.

Some GuestMemory implementations, like GuestMemoryMmap, have the capability to mmap the guest address range into virtual address space of the host for direct access, so the corresponding host virtual address may be passed to other subsystems.

§Note

The underlying guest memory is not protected from memory aliasing, which breaks the Rust memory safety model. It’s the caller’s responsibility to ensure that there’s no concurrent accesses to the underlying guest memory.

§Arguments
  • addr - Guest address to convert.
§Examples (uses the backend-mmap feature)
let addr = gm
    .get_host_address(GuestAddress(0x1200))
    .expect("Could not get host address");
println!("Host address is {:p}", addr);
source

fn get_slice( &self, addr: GuestAddress, count: usize ) -> Result<VolatileSlice<'_, MS<'_, Self>>>

Returns a VolatileSlice of count bytes starting at addr.

Object Safety§

This trait is not object safe.

Implementors§