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 <bchen@crusoe.ai>
This commit is contained in:
Bo Chen 2025-05-05 14:59:56 -07:00
parent 8da7c13e26
commit 2f21827430

View file

@ -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
))
})?;
}
}
}
}