diff --git a/devices/src/ivshmem.rs b/devices/src/ivshmem.rs index dc85039c7..f1d4c2cc0 100644 --- a/devices/src/ivshmem.rs +++ b/devices/src/ivshmem.rs @@ -49,6 +49,8 @@ pub enum IvshmemError { CreateUserspaceMapping(#[source] anyhow::Error), #[error("Failed to remove old userspace mapping.")] RemoveUserspaceMapping(#[source] anyhow::Error), + #[error("Missing memory region")] + MissingMemoryRegion, } #[derive(Copy, Clone)] @@ -70,6 +72,12 @@ pub trait IvshmemOps: Send + Sync { backing_file: Option, ) -> Result<(Arc, UserspaceMapping), IvshmemError>; + fn create_userspace_mapping( + &mut self, + start_addr: u64, + region: Arc, + ) -> Result; + fn unmap_ram_region(&mut self, mapping: UserspaceMapping) -> Result<(), IvshmemError>; } @@ -94,7 +102,6 @@ pub struct IvshmemDevice { region_size: u64, ivshmem_ops: Arc>, - backend_file: Option, region: Option>, userspace_mapping: Option, } @@ -111,7 +118,6 @@ impl IvshmemDevice { pub fn new( id: String, region_size: u64, - backend_file: Option, ivshmem_ops: Arc>, snapshot: Option<&Snapshot>, ) -> Result { @@ -159,7 +165,6 @@ impl IvshmemDevice { ivshmem_ops, region: None, userspace_mapping: None, - backend_file, } } else { IvshmemDevice { @@ -174,7 +179,6 @@ impl IvshmemDevice { ivshmem_ops, region: None, userspace_mapping: None, - backend_file, } }; Ok(device) @@ -353,6 +357,10 @@ impl PciDevice for IvshmemDevice { fn move_bar(&mut self, old_base: u64, new_base: u64) -> io::Result<()> { if new_base == self.data_bar_addr() { + let region = self + .region + .clone() + .ok_or_else(|| io::Error::other(IvshmemError::MissingMemoryRegion))?; if let Some(old_mapping) = self.userspace_mapping.take() { self.ivshmem_ops .lock() @@ -360,17 +368,13 @@ impl PciDevice for IvshmemDevice { .unmap_ram_region(old_mapping) .map_err(io::Error::other)?; } - let (region, new_mapping) = self + let new_mapping = self .ivshmem_ops .lock() .unwrap() - .map_ram_region( - new_base, - self.region_size as usize, - self.backend_file.clone(), - ) + .create_userspace_mapping(new_base, region) .map_err(io::Error::other)?; - self.set_region(region, new_mapping); + self.userspace_mapping = Some(new_mapping); } for bar in self.bar_regions.iter_mut() { if bar.addr() == old_base { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 1eda66472..8c0b75244 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -4676,7 +4676,6 @@ impl DeviceManager { devices::IvshmemDevice::new( id.clone(), ivshmem_cfg.size as u64, - Some(ivshmem_cfg.path.clone()), ivshmem_ops.clone(), snapshot, ) @@ -5601,6 +5600,16 @@ impl IvshmemOps for IvshmemHandler { false, ) .map_err(|e| IvshmemError::CreateUserMemoryRegion(e.into()))?; + let region = Arc::new(region); + let mapping = self.create_userspace_mapping(start_addr, region.clone())?; + Ok((region, mapping)) + } + + fn create_userspace_mapping( + &mut self, + start_addr: u64, + region: Arc>, + ) -> Result { let mem_slot = { let mut manager = self.memory_manager.lock().unwrap(); // SAFETY: guaranteed by MmapRegion invariants @@ -5616,14 +5625,12 @@ impl IvshmemOps for IvshmemHandler { } } .map_err(|e| IvshmemError::CreateUserspaceMapping(e.into()))?; - let region = Arc::new(region); - let mapping = UserspaceMapping { - mapping: region.clone(), + Ok(UserspaceMapping { + mapping: region, mem_slot, addr: GuestAddress(start_addr), mergeable: false, - }; - Ok((region, mapping)) + }) } fn unmap_ram_region(&mut self, mapping: UserspaceMapping) -> Result<(), IvshmemError> {