Skip to main content

axvirtio_common/
memory.rs

1//! Scoped guest-memory operations used by VirtIO queues.
2
3use ax_memory_addr::PhysAddr;
4use axaddrspace::GuestMemoryAccessor;
5use axvm_types::GuestPhysAddr;
6
7use crate::{VirtioError, VirtioResult};
8
9/// The minimum guest-memory capability required by a VirtIO queue operation.
10pub trait GuestMemory {
11    /// Reads bytes starting at `guest_addr`.
12    fn read(&mut self, guest_addr: GuestPhysAddr, data: &mut [u8]) -> VirtioResult<()>;
13
14    /// Writes bytes starting at `guest_addr`.
15    fn write(&mut self, guest_addr: GuestPhysAddr, data: &[u8]) -> VirtioResult<()>;
16}
17
18/// Placeholder accessor for runtimes that provide guest memory only through
19/// a scoped [`GuestMemory`] capability at queue-processing time.
20#[derive(Clone, Copy, Debug, Default)]
21pub struct NoGuestMemoryAccessor;
22
23impl GuestMemoryAccessor for NoGuestMemoryAccessor {
24    fn translate_and_get_limit(&self, _guest_addr: GuestPhysAddr) -> Option<(PhysAddr, usize)> {
25        None
26    }
27}
28
29/// Adapter for existing address-space accessors used by host tests and
30/// standalone device-model users.
31pub struct AddressSpaceMemory<'a, T> {
32    accessor: &'a T,
33}
34
35impl<'a, T> AddressSpaceMemory<'a, T> {
36    /// Wraps one address-space accessor for a scoped queue operation.
37    pub const fn new(accessor: &'a T) -> Self {
38        Self { accessor }
39    }
40}
41
42impl<T: GuestMemoryAccessor> GuestMemory for AddressSpaceMemory<'_, T> {
43    fn read(&mut self, guest_addr: GuestPhysAddr, data: &mut [u8]) -> VirtioResult<()> {
44        self.accessor
45            .read_buffer(guest_addr, data)
46            .map_err(|_| VirtioError::InvalidAddress)
47    }
48
49    fn write(&mut self, guest_addr: GuestPhysAddr, data: &[u8]) -> VirtioResult<()> {
50        self.accessor
51            .write_buffer(guest_addr, data)
52            .map_err(|_| VirtioError::InvalidAddress)
53    }
54}