From 2f21827430611833ecaf3ce656010b848abef4a9 Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Mon, 5 May 2025 14:59:56 -0700 Subject: [PATCH] pci: vfio: Update IOMMU mappings of MMIO regions with BAR reprogram To support PCIe P2P between VFIO devices, we populate IOMMU mappings for the non-emulated MMIO regions of all VFIO devices via `VFIO_IOMMU_MAP_DMA` (f0c1f8d), but the patch did not properly update the IOMMU mappings with BAR reprogramming. Fixes: #7027 Signed-off-by: Bo Chen --- pci/src/vfio.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index f4b2ce97c..bbdbdd747 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -1893,6 +1893,23 @@ impl PciDevice for VfioPciDevice { region.start = GuestAddress(new_base); for user_memory_region in region.user_memory_regions.iter_mut() { + // Unmap the old MMIO region from vfio container + if !self.iommu_attached { + if let Err(e) = self + .container + .vfio_dma_unmap(user_memory_region.start, user_memory_region.size) + .map_err(|e| { + VfioPciError::DmaUnmap(e, self.device_path.clone(), self.bdf) + }) + { + error!( + "Could not unmap mmio region from vfio container: \ + iova 0x{:x}, size 0x{:x}: {}, ", + user_memory_region.start, user_memory_region.size, e + ); + } + } + // Remove old region let old_mem_region = self.vm.make_user_memory_region( user_memory_region.slot, @@ -1927,6 +1944,26 @@ impl PciDevice for VfioPciDevice { self.vm .create_user_memory_region(new_mem_region) .map_err(io::Error::other)?; + + // Map the moved mmio region to vfio container + if !self.iommu_attached { + self.container + .vfio_dma_map( + user_memory_region.start, + user_memory_region.size, + user_memory_region.host_addr, + ) + .map_err(|e| { + VfioPciError::DmaMap(e, self.device_path.clone(), self.bdf) + }) + .map_err(|e| { + io::Error::other(format!( + "Could not map mmio region to vfio container: \ + iova 0x{:x}, size 0x{:x}: {}, ", + user_memory_region.start, user_memory_region.size, e + )) + })?; + } } } }