vfio-pci: Unmap and retry DMA mapping
Occasionally we get regions added that overlap with existing mappings. These always seems to be in the VGA ROM range. VFIO returns EBUSY for these mapping attempts. We can try a little harder and assume that the latest mapping is correct by removing any overlapping ranges and retrying the original request. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
parent
af6bc27e39
commit
12af134487
@ -819,12 +819,19 @@ static int vfio_dma_map(VFIOContainer *container, target_phys_addr_t iova,
|
||||
map.flags |= VFIO_DMA_MAP_FLAG_WRITE;
|
||||
}
|
||||
|
||||
if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map)) {
|
||||
DPRINTF("VFIO_MAP_DMA: %d\n", -errno);
|
||||
return -errno;
|
||||
/*
|
||||
* Try the mapping, if it fails with EBUSY, unmap the region and try
|
||||
* again. This shouldn't be necessary, but we sometimes see it in
|
||||
* the the VGA ROM space.
|
||||
*/
|
||||
if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 ||
|
||||
(errno == EBUSY && vfio_dma_unmap(container, iova, size) == 0 &&
|
||||
ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
DPRINTF("VFIO_MAP_DMA: %d\n", -errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
static void vfio_listener_dummy1(MemoryListener *listener)
|
||||
|
Loading…
Reference in New Issue
Block a user