Trait vm_memory::guest_memory::GuestMemory
source · pub trait GuestMemory {
type R: GuestMemoryRegion;
type I: for<'a> GuestMemoryIterator<'a, Self::R>;
Show 15 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 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§
sourcetype R: GuestMemoryRegion
type R: GuestMemoryRegion
Type of objects hosted by the address space.
sourcetype I: for<'a> GuestMemoryIterator<'a, Self::R>
type I: for<'a> GuestMemoryIterator<'a, Self::R>
Lifetime generic associated iterators. Usually this is just Self
.
Required Methods§
sourcefn num_regions(&self) -> usize
fn num_regions(&self) -> usize
Returns the number of regions in the collection.
sourcefn find_region(&self, addr: GuestAddress) -> Option<&Self::R>
fn find_region(&self, addr: GuestAddress) -> Option<&Self::R>
Returns the region containing the specified address or None
.
sourcefn iter(&self) -> <Self::I as GuestMemoryIterator<'_, Self::R>>::Iter
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§
sourcefn with_regions<F, E>(&self, cb: F) -> Result<(), E>
👎Deprecated since 0.6.0: Use .iter()
instead
fn with_regions<F, E>(&self, cb: F) -> Result<(), E>
.iter()
insteadPerform the specified action on each region.
It only walks children of current region and does not step into sub regions.
sourcefn with_regions_mut<F, E>(&self, cb: F) -> Result<(), E>
👎Deprecated since 0.6.0: Use .iter()
instead
fn with_regions_mut<F, E>(&self, cb: F) -> Result<(), E>
.iter()
insteadPerform the specified action on each region mutably.
It only walks children of current region and does not step into sub regions.
sourcefn map_and_fold<F, G, T>(&self, init: T, mapf: F, foldf: G) -> T
👎Deprecated since 0.6.0: Use .iter()
instead
fn map_and_fold<F, G, T>(&self, init: T, mapf: F, foldf: G) -> T
.iter()
insteadApplies two functions, specified as callbacks, on the inner memory regions.
§Arguments
init
- Starting value of the accumulator for thefoldf
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 bymapf
. It acts as an operator, applying itself to theinit
value and to each subsequent elemnent in the array returned bymapf
.
§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)
sourcefn last_addr(&self) -> GuestAddress
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()));
sourcefn to_region_addr(
&self,
addr: GuestAddress,
) -> Option<(&Self::R, MemoryRegionAddress)>
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.
sourcefn address_in_range(&self, addr: GuestAddress) -> bool
fn address_in_range(&self, addr: GuestAddress) -> bool
Returns true
if the given address is present within the memory of the guest.
sourcefn check_address(&self, addr: GuestAddress) -> Option<GuestAddress>
fn check_address(&self, addr: GuestAddress) -> Option<GuestAddress>
Returns the given address if it is present within the memory of the guest.
sourcefn check_range(&self, base: GuestAddress, len: usize) -> bool
fn check_range(&self, base: GuestAddress, len: usize) -> bool
Check whether the range [base, base + len) is valid.
sourcefn checked_offset(
&self,
base: GuestAddress,
offset: usize,
) -> Option<GuestAddress>
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.
sourcefn try_access<F>(&self, count: usize, addr: GuestAddress, f: F) -> Result<usize>
fn try_access<F>(&self, count: usize, addr: GuestAddress, f: F) -> 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
sourcefn get_host_address(&self, addr: GuestAddress) -> Result<*mut u8>
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);
sourcefn get_slice(
&self,
addr: GuestAddress,
count: usize,
) -> Result<VolatileSlice<'_, MS<'_, Self>>>
fn get_slice( &self, addr: GuestAddress, count: usize, ) -> Result<VolatileSlice<'_, MS<'_, Self>>>
Returns a VolatileSlice
of count
bytes starting at
addr
.