Skip to content

Commit 460f4da

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 ccb8b63 commit 460f4da

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

src/mmap/mod.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use std::borrow::Borrow;
1616
use std::ops::Deref;
1717
use std::result;
18+
use std::sync::Arc;
1819

1920
use crate::address::Address;
2021
use crate::bitmap::{Bitmap, BS};
@@ -54,15 +55,15 @@ pub use windows::MmapRegion;
5455
/// in the virtual address space of the calling process.
5556
#[derive(Debug)]
5657
pub struct GuestRegionMmap<B = ()> {
57-
mapping: MmapRegion<B>,
58+
mapping: Arc<MmapRegion<B>>,
5859
guest_base: GuestAddress,
5960
}
6061

6162
impl<B> Deref for GuestRegionMmap<B> {
6263
type Target = MmapRegion<B>;
6364

6465
fn deref(&self) -> &MmapRegion<B> {
65-
&self.mapping
66+
self.mapping.as_ref()
6667
}
6768
}
6869

@@ -71,6 +72,11 @@ impl<B: Bitmap> GuestRegionMmap<B> {
7172
///
7273
/// Returns `None` if `guest_base` + `mapping.len()` would overflow.
7374
pub fn new(mapping: MmapRegion<B>, guest_base: GuestAddress) -> Option<Self> {
75+
Self::with_arc(Arc::new(mapping), guest_base)
76+
}
77+
78+
/// Same as [`Self::new()`], but takes an `Arc`-wrapped `mapping`.
79+
pub fn with_arc(mapping: Arc<MmapRegion<B>>, guest_base: GuestAddress) -> Option<Self> {
7480
guest_base
7581
.0
7682
.checked_add(mapping.size() as u64)
@@ -79,6 +85,16 @@ impl<B: Bitmap> GuestRegionMmap<B> {
7985
guest_base,
8086
})
8187
}
88+
89+
/// Return a reference to the inner `Arc<MmapRegion>` (as opposed to
90+
/// [`.deref()`](Self::deref()), which does not reference the `Arc`).
91+
///
92+
/// The returned reference can be cloned to construct a new `GuestRegionMmap` with a different
93+
/// base address (e.g. when switching between memory address spaces based on the guest physical
94+
/// address vs. the VMM userspace virtual address).
95+
pub fn get_mapping(&self) -> &Arc<MmapRegion<B>> {
96+
&self.mapping
97+
}
8298
}
8399

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

0 commit comments

Comments
 (0)