Trait guestmem::GuestMemoryAccess
source · pub unsafe trait GuestMemoryAccess:
'static
+ Send
+ Sync {
// Required methods
fn mapping(&self) -> Option<NonNull<u8>>;
fn max_address(&self) -> u64;
// Provided methods
fn access_bitmap(&self) -> Option<BitmapInfo> { ... }
fn subrange(
&self,
offset: u64,
len: u64,
allow_preemptive_locking: bool,
) -> Result<Option<GuestMemory>, GuestMemoryBackingError> { ... }
fn page_fault(
&self,
address: u64,
len: usize,
write: bool,
bitmap_failure: bool,
) -> PageFaultAction { ... }
unsafe fn read_fallback(
&self,
addr: u64,
dest: *mut u8,
len: usize,
) -> Result<(), GuestMemoryBackingError> { ... }
unsafe fn write_fallback(
&self,
addr: u64,
src: *const u8,
len: usize,
) -> Result<(), GuestMemoryBackingError> { ... }
fn fill_fallback(
&self,
addr: u64,
val: u8,
len: usize,
) -> Result<(), GuestMemoryBackingError> { ... }
fn compare_exchange_fallback(
&self,
addr: u64,
current: &mut [u8],
new: &[u8],
) -> Result<bool, GuestMemoryBackingError> { ... }
fn expose_va(
&self,
address: u64,
len: u64,
) -> Result<(), GuestMemoryBackingError> { ... }
fn base_iova(&self) -> Option<u64> { ... }
}
Expand description
A trait for a guest memory backing.
Guest memory may be backed by a virtual memory mapping, in which case this trait can provide the VA and length of that mapping. Alternatively, it may be backed by some other means, in which case this trait can provide fallback methods for reading and writing memory.
Memory access should first be attempted via the virtual address mapping. If
this fails or is not present, the caller should fall back to read_fallback
or write_fallback
. This allows an implementation to have a fast path using
the mapping, and a slow path using the fallback functions.
§Safety
The implementor must follow the contract for each method.
Required Methods§
sourcefn mapping(&self) -> Option<NonNull<u8>>
fn mapping(&self) -> Option<NonNull<u8>>
Returns a stable VA mapping for guest memory.
The size of the mapping is the same as max_address
.
The VA is guaranteed to remain reserved, but individual ranges may be uncommitted.
sourcefn max_address(&self) -> u64
fn max_address(&self) -> u64
The maximum address that can be passed to the *_fallback
methods, as
well as the maximum offset into the VA range described by mapping
.
Provided Methods§
sourcefn access_bitmap(&self) -> Option<BitmapInfo>
fn access_bitmap(&self) -> Option<BitmapInfo>
The bitmaps to check for validity, one bit per page. If a bit is set, then the page is valid to access via the mapping; if it is clear, then the page will not be accessed.
The bitmaps must be at least ceil(bitmap_start + max_address() / PAGE_SIZE)
bits long, and they must be valid for atomic read access for
the lifetime of this object from any thread.
The bitmaps are only checked if there is a mapping. If the bitmap check
fails, then the associated *_fallback
routine is called to handle the
error.
TODO: add a synchronization scheme.
fn subrange( &self, offset: u64, len: u64, allow_preemptive_locking: bool, ) -> Result<Option<GuestMemory>, GuestMemoryBackingError>
sourcefn page_fault(
&self,
address: u64,
len: usize,
write: bool,
bitmap_failure: bool,
) -> PageFaultAction
fn page_fault( &self, address: u64, len: usize, write: bool, bitmap_failure: bool, ) -> PageFaultAction
Called when access to memory via the mapped range fails, either due to a bitmap failure or due to a failure when accessing the virtual address.
address
is the address where the access failed. len
is the remainder
of the access; it is not necessarily the case that all len
bytes are
inaccessible in the bitmap or mapping.
Returns whether the faulting operation should be retried, failed, or that
one of the fallback operations (e.g. read_fallback
) should be called.
sourceunsafe fn read_fallback(
&self,
addr: u64,
dest: *mut u8,
len: usize,
) -> Result<(), GuestMemoryBackingError>
unsafe fn read_fallback( &self, addr: u64, dest: *mut u8, len: usize, ) -> Result<(), GuestMemoryBackingError>
Fallback called if a read fails via direct access to mapped_range
.
This is only called if mapping()
returns None
or if page_fault()
returns PageFaultAction::Fallback
.
Implementors must ensure that dest[..len]
is fully initialized on
successful return.
§Safety
The caller must ensure that dest[..len]
is valid for write. Note,
however, that dest
might be aliased by other threads, the guest, or
the kernel.
sourceunsafe fn write_fallback(
&self,
addr: u64,
src: *const u8,
len: usize,
) -> Result<(), GuestMemoryBackingError>
unsafe fn write_fallback( &self, addr: u64, src: *const u8, len: usize, ) -> Result<(), GuestMemoryBackingError>
Fallback called if a write fails via direct access to mapped_range
.
This is only called if mapping()
returns None
or if page_fault()
returns PageFaultAction::Fallback
.
§Safety
The caller must ensure that src[..len]
is valid for read. Note,
however, that src
might be aliased by other threads, the guest, or
the kernel.
sourcefn fill_fallback(
&self,
addr: u64,
val: u8,
len: usize,
) -> Result<(), GuestMemoryBackingError>
fn fill_fallback( &self, addr: u64, val: u8, len: usize, ) -> Result<(), GuestMemoryBackingError>
Fallback called if a fill fails via direct access to mapped_range
.
This is only called if mapping()
returns None
or if page_fault()
returns PageFaultAction::Fallback
.
sourcefn compare_exchange_fallback(
&self,
addr: u64,
current: &mut [u8],
new: &[u8],
) -> Result<bool, GuestMemoryBackingError>
fn compare_exchange_fallback( &self, addr: u64, current: &mut [u8], new: &[u8], ) -> Result<bool, GuestMemoryBackingError>
Fallback called if a compare exchange fails via direct access to mapped_range
.
On compare failure, returns Ok(false)
and updates current
.
This is only called if mapping()
returns None
or if page_fault()
returns PageFaultAction::Fallback
.