Skip to content

Commit 073c0bb

Browse files
committed
mmap: Wrap MmapRegion in Arc<>
The vhost-user-backend crate will need to be able to modify all existing memory regions to use the VMM user address instead of the guest physical address once the IOMMU feature is switched on, and vice versa. To do so, it needs to be able to modify regions’ base address. Because `GuestMemoryMmap` stores regions wrapped in an `Arc<_>`, we cannot mutate them after they have been put into the `GuestMemoryMmap` object; and `MmapRegion` itself is by its nature not clonable. So to modify the regions’ base addresses, we need some way to create a new `GuestRegionMmap` referencing the same `MmapRegion` as another one, but with a different base address. We can do that by having `GuestRegionMmap` wrap its `MmapRegion` in an `Arc`, and adding a method to return a reference to that `Arc`, and a method to construct a `GuestRegionMmap` object from such a cloned `Arc.` Signed-off-by: Hanna Czenczek <[email protected]>
1 parent 0848071 commit 073c0bb

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

src/mmap/mod.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,21 +77,29 @@ pub enum Error {
7777
/// in the virtual address space of the calling process.
7878
#[derive(Debug)]
7979
pub struct GuestRegionMmap<B = ()> {
80-
mapping: MmapRegion<B>,
80+
mapping: Arc<MmapRegion<B>>,
8181
guest_base: GuestAddress,
8282
}
8383

8484
impl<B> Deref for GuestRegionMmap<B> {
8585
type Target = MmapRegion<B>;
8686

8787
fn deref(&self) -> &MmapRegion<B> {
88-
&self.mapping
88+
self.mapping.as_ref()
8989
}
9090
}
9191

9292
impl<B: Bitmap> GuestRegionMmap<B> {
9393
/// Create a new memory-mapped memory region for the guest's physical memory.
9494
pub fn new(mapping: MmapRegion<B>, guest_base: GuestAddress) -> result::Result<Self, Error> {
95+
Self::with_arc(Arc::new(mapping), guest_base)
96+
}
97+
98+
/// Same as [`Self::new()`], but takes an `Arc`-wrapped `mapping`.
99+
pub fn with_arc(
100+
mapping: Arc<MmapRegion<B>>,
101+
guest_base: GuestAddress,
102+
) -> result::Result<Self, Error> {
95103
if guest_base.0.checked_add(mapping.size() as u64).is_none() {
96104
return Err(Error::InvalidGuestRegion);
97105
}
@@ -101,6 +109,16 @@ impl<B: Bitmap> GuestRegionMmap<B> {
101109
guest_base,
102110
})
103111
}
112+
113+
/// Return a reference to the inner `Arc<MmapRegion>` (as opposed to
114+
/// [`.deref()`](Self::deref()), which does not reference the `Arc`).
115+
///
116+
/// The returned reference can be cloned to construct a new `GuestRegionMmap` with a different
117+
/// base address (e.g. when switching between memory address spaces based on the guest physical
118+
/// address vs. the VMM userspace virtual address).
119+
pub fn get_mapping(&self) -> &Arc<MmapRegion<B>> {
120+
&self.mapping
121+
}
104122
}
105123

106124
#[cfg(not(feature = "xen"))]

0 commit comments

Comments
 (0)