diff --git a/vm-virtio/src/transport/pci_device.rs b/vm-virtio/src/transport/pci_device.rs index 482faea2d..76e048e28 100755 --- a/vm-virtio/src/transport/pci_device.rs +++ b/vm-virtio/src/transport/pci_device.rs @@ -300,6 +300,9 @@ pub struct VirtioPciDevice { // needed when the guest tries to early access the virtio configuration of // a device. cap_pci_cfg_info: VirtioPciCfgCapInfo, + + // Details of bar regions to free + bar_regions: Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, } impl VirtioPciDevice { @@ -402,6 +405,7 @@ impl VirtioPciDevice { use_64bit_bar, interrupt_source_group, cap_pci_cfg_info: VirtioPciCfgCapInfo::default(), + bar_regions: vec![], }; if let Some(msix_config) = &virtio_pci_device.msix_config { @@ -721,6 +725,8 @@ impl PciDevice for VirtioPciDevice { ranges.push((addr, CAPABILITY_BAR_SIZE, region_type)); (addr, region_type) }; + self.bar_regions + .push((virtio_pci_bar_addr, CAPABILITY_BAR_SIZE, region_type)); let config = PciBarConfiguration::default() .set_register_index(0) @@ -763,6 +769,24 @@ impl PciDevice for VirtioPciDevice { Ok(ranges) } + fn free_bars( + &mut self, + allocator: &mut SystemAllocator, + ) -> std::result::Result<(), PciDeviceError> { + for (addr, length, type_) in self.bar_regions.drain(..) { + match type_ { + PciBarRegionType::Memory32BitRegion => { + allocator.free_mmio_hole_addresses(addr, length); + } + PciBarRegionType::Memory64BitRegion => { + allocator.free_mmio_addresses(addr, length); + } + _ => error!("Unexpected PCI bar type"), + } + } + Ok(()) + } + fn read_bar(&mut self, _base: u64, offset: u64, data: &mut [u8]) { match offset { o if o < COMMON_CONFIG_BAR_OFFSET + COMMON_CONFIG_SIZE => self.common_config.read(