diff --git a/pci/src/bus.rs b/pci/src/bus.rs index e62d52064..1a302b5fc 100644 --- a/pci/src/bus.rs +++ b/pci/src/bus.rs @@ -88,6 +88,10 @@ impl PciDevice for PciRoot { fn as_any(&mut self) -> &mut dyn Any { self } + + fn id(&self) -> Option { + None + } } pub struct PciBus { diff --git a/pci/src/device.rs b/pci/src/device.rs index 407d31360..05a99dbe9 100644 --- a/pci/src/device.rs +++ b/pci/src/device.rs @@ -110,6 +110,9 @@ pub trait PciDevice: BusDevice { /// Provides a mutable reference to the Any trait. This is useful to let /// the caller have access to the underlying type behind the trait. fn as_any(&mut self) -> &mut dyn Any; + + /// Optionally returns a unique identifier. + fn id(&self) -> Option; } /// This trait defines a set of functions which can be triggered whenever a diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index e14bbc877..410b31f60 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -976,6 +976,7 @@ impl VfioCommon { /// The VMM creates a VfioDevice, then assigns it to a VfioPciDevice, /// which then gets added to the PCI bus. pub struct VfioPciDevice { + id: String, vm: Arc, device: Arc, container: Arc, @@ -986,7 +987,9 @@ pub struct VfioPciDevice { impl VfioPciDevice { /// Constructs a new Vfio Pci device for the given Vfio device + #[allow(clippy::too_many_arguments)] pub fn new( + id: String, vm: &Arc, device: VfioDevice, container: Arc, @@ -1027,6 +1030,7 @@ impl VfioPciDevice { common.initialize_legacy_interrupt(legacy_interrupt_group, &vfio_wrapper)?; let vfio_pci_device = VfioPciDevice { + id, vm: vm.clone(), device, container, @@ -1438,4 +1442,8 @@ impl PciDevice for VfioPciDevice { fn as_any(&mut self) -> &mut dyn Any { self } + + fn id(&self) -> Option { + Some(self.id.clone()) + } } diff --git a/pci/src/vfio_user.rs b/pci/src/vfio_user.rs index 0a572b4ec..df30596d7 100644 --- a/pci/src/vfio_user.rs +++ b/pci/src/vfio_user.rs @@ -30,6 +30,7 @@ use vm_memory::{ use vmm_sys_util::eventfd::EventFd; pub struct VfioUserPciDevice { + id: String, vm: Arc, client: Arc>, vfio_wrapper: VfioUserClientWrapper, @@ -63,6 +64,7 @@ impl PciSubclass for PciVfioUserSubclass { impl VfioUserPciDevice { pub fn new( + id: String, vm: &Arc, client: Arc>, msi_interrupt_manager: &Arc>, @@ -111,6 +113,7 @@ impl VfioUserPciDevice { .map_err(VfioUserPciDeviceError::InitializeLegacyInterrupts)?; Ok(Self { + id, vm: vm.clone(), client, vfio_wrapper, @@ -486,6 +489,10 @@ impl PciDevice for VfioUserPciDevice { Ok(()) } + + fn id(&self) -> Option { + Some(self.id.clone()) + } } impl Drop for VfioUserPciDevice { diff --git a/virtio-devices/src/transport/pci_device.rs b/virtio-devices/src/transport/pci_device.rs index bcf88911b..92a8c842b 100644 --- a/virtio-devices/src/transport/pci_device.rs +++ b/virtio-devices/src/transport/pci_device.rs @@ -1089,6 +1089,10 @@ impl PciDevice for VirtioPciDevice { fn as_any(&mut self) -> &mut dyn Any { self } + + fn id(&self) -> Option { + Some(self.id.clone()) + } } impl BusDevice for VirtioPciDevice { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index a4b5fca39..7281b01ef 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -660,22 +660,30 @@ impl DeviceRelocation for AddressManager { } } - let any_dev = pci_dev.as_any(); - if let Some(virtio_pci_dev) = any_dev.downcast_ref::() { - // Update the device_tree resources associated with the device - if let Some(node) = self - .device_tree - .lock() - .unwrap() - .get_mut(&virtio_pci_dev.id()) - { + // Update the device_tree resources associated with the device + if let Some(id) = pci_dev.id() { + if let Some(node) = self.device_tree.lock().unwrap().get_mut(&id) { let mut resource_updated = false; for resource in node.resources.iter_mut() { - if let Resource::MmioAddressRange { base, .. } = resource { - if *base == old_base { - *base = new_base; - resource_updated = true; - break; + match region_type { + PciBarRegionType::IoRegion => { + if let Resource::PioAddressRange { base, .. } = resource { + if *base as u64 == old_base { + *base = new_base as u16; + resource_updated = true; + break; + } + } + } + PciBarRegionType::Memory32BitRegion + | PciBarRegionType::Memory64BitRegion => { + if let Resource::MmioAddressRange { base, .. } = resource { + if *base == old_base { + *base = new_base; + resource_updated = true; + break; + } + } } } } @@ -685,21 +693,20 @@ impl DeviceRelocation for AddressManager { io::ErrorKind::Other, format!( "Couldn't find a resource with base 0x{:x} for device {}", - old_base, - virtio_pci_dev.id() + old_base, id ), )); } } else { return Err(io::Error::new( io::ErrorKind::Other, - format!( - "Couldn't find device {} from device tree", - virtio_pci_dev.id() - ), + format!("Couldn't find device {} from device tree", id), )); } + } + let any_dev = pci_dev.as_any(); + if let Some(virtio_pci_dev) = any_dev.downcast_ref::() { let bar_addr = virtio_pci_dev.config_bar_addr(); if bar_addr == new_base { for (event, addr) in virtio_pci_dev.ioeventfds(old_base) { @@ -3184,6 +3191,7 @@ impl DeviceManager { }; let vfio_pci_device = VfioPciDevice::new( + vfio_name.clone(), &self.address_manager.vm, vfio_device, vfio_container, @@ -3354,6 +3362,7 @@ impl DeviceManager { )); let mut vfio_user_pci_device = VfioUserPciDevice::new( + vfio_user_name.clone(), &self.address_manager.vm, client.clone(), &self.msi_interrupt_manager,