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:
Alex Williamson 2012-10-08 08:45:29 -06:00
parent af6bc27e39
commit 12af134487

View File

@ -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)