Struct vm_memory::guest_memory::GuestMemory
source · 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
impl GuestMemory
sourcepub fn remove_range(&self, addr: GuestAddress, count: u64) -> Result<()>
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.
sourcepub fn set_memory_policy(&self, mem_policy: MemoryPolicy)
pub fn set_memory_policy(&self, mem_policy: MemoryPolicy)
Handles guest memory policy hints/advices.
pub fn use_dontfork(&self) -> Result<()>
source§impl GuestMemory
impl GuestMemory
sourcefn create_shm(
ranges: &[(GuestAddress, u64, MemoryRegionOptions)]
) -> Result<SharedMemory>
fn create_shm( ranges: &[(GuestAddress, u64, MemoryRegionOptions)] ) -> Result<SharedMemory>
Creates backing shm for GuestMemory regions
sourcepub fn new_with_options(
ranges: &[(GuestAddress, u64, MemoryRegionOptions)]
) -> Result<GuestMemory>
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)
sourcepub fn new(ranges: &[(GuestAddress, u64)]) -> Result<GuestMemory>
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.
sourcepub fn from_regions(regions: Vec<MemoryRegion>) -> Result<Self>
pub fn from_regions(regions: Vec<MemoryRegion>) -> Result<Self>
Creates a GuestMemory
from a collection of MemoryRegions.
sourcepub fn end_addr(&self) -> GuestAddress
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(())
sourcepub fn guest_memory_regions(&self) -> Vec<(GuestAddress, usize)>
pub fn guest_memory_regions(&self) -> Vec<(GuestAddress, usize)>
Returns the guest addresses and sizes of the memory regions.
sourcepub fn memory_size(&self) -> u64
pub fn memory_size(&self) -> u64
Returns the total size of memory in bytes.
sourcepub fn address_in_range(&self, addr: GuestAddress) -> bool
pub fn address_in_range(&self, addr: GuestAddress) -> bool
Returns true if the given address is within the memory range available to the guest.
sourcepub fn range_overlap(&self, start: GuestAddress, end: GuestAddress) -> bool
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.
sourcepub fn checked_offset(
&self,
addr: GuestAddress,
offset: u64
) -> Option<GuestAddress>
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.
sourcepub fn is_valid_range(&self, start: GuestAddress, length: u64) -> bool
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.
sourcepub fn num_regions(&self) -> u64
pub fn num_regions(&self) -> u64
Returns the size of the memory region in bytes.
pub fn regions(&self) -> impl Iterator<Item = MemoryRegionInformation<'_>>
sourcepub fn write_at_addr(
&self,
buf: &[u8],
guest_addr: GuestAddress
) -> Result<usize>
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(())
sourcepub fn write_all_at_addr(
&self,
buf: &[u8],
guest_addr: GuestAddress
) -> Result<()>
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))
}
sourcepub fn read_at_addr(
&self,
buf: &mut [u8],
guest_addr: GuestAddress
) -> Result<usize>
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(())
sourcepub fn read_exact_at_addr(
&self,
buf: &mut [u8],
guest_addr: GuestAddress
) -> Result<()>
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))
}
sourcepub fn read_obj_from_addr<T: FromBytes>(
&self,
guest_addr: GuestAddress
) -> Result<T>
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(|_| ())?;
sourcepub fn read_obj_from_addr_volatile<T: FromBytes>(
&self,
guest_addr: GuestAddress
) -> Result<T>
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(|_| ())?;
sourcepub fn write_obj_at_addr<T: AsBytes>(
&self,
val: T,
guest_addr: GuestAddress
) -> Result<()>
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(|_| ())
sourcepub fn write_obj_at_addr_volatile<T: AsBytes>(
&self,
val: T,
guest_addr: GuestAddress
) -> Result<()>
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(|_| ())
sourcepub fn get_slice_at_addr(
&self,
addr: GuestAddress,
len: usize
) -> Result<VolatileSlice<'_>>
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);
sourcepub fn get_host_address(&self, guest_addr: GuestAddress) -> Result<*const u8>
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(())
sourcepub fn get_host_address_range(
&self,
guest_addr: GuestAddress,
size: usize
) -> Result<*const u8>
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(())
sourcepub fn shm_region(
&self,
guest_addr: GuestAddress
) -> Result<&(dyn AsRawDescriptor + Send + Sync)>
pub fn shm_region( &self, guest_addr: GuestAddress ) -> Result<&(dyn AsRawDescriptor + Send + Sync)>
Returns a reference to the region that backs the given address.
sourcepub fn offset_region(
&self,
offset: u64
) -> Result<&(dyn AsRawDescriptor + Send + Sync)>
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.
sourcepub fn find_region(
&self,
guest_addr: GuestAddress
) -> Result<(&MemoryMapping, usize, u64)>
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.
sourcepub fn offset_from_base(&self, guest_addr: GuestAddress) -> Result<u64>
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);
sourcepub unsafe fn snapshot<T: Write>(
&self,
w: &mut T,
compress: bool
) -> Result<Value>
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.
sourcepub unsafe fn restore<T: Read>(&self, metadata: Value, r: &mut T) -> Result<()>
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
impl AsRawDescriptors for GuestMemory
source§fn as_raw_descriptors(&self) -> Vec<RawDescriptor>
fn as_raw_descriptors(&self) -> Vec<RawDescriptor>
USE WITH CAUTION, the descriptors returned here are not necessarily files!
source§impl BackingMemory for GuestMemory
impl BackingMemory for GuestMemory
source§fn get_volatile_slice(&self, mem_range: MemRegion) -> Result<VolatileSlice<'_>>
fn get_volatile_slice(&self, mem_range: MemRegion) -> Result<VolatileSlice<'_>>
source§impl Clone for GuestMemory
impl Clone for GuestMemory
source§fn clone(&self) -> GuestMemory
fn clone(&self) -> GuestMemory
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more