[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: question regarding QEMU adding overlapping memory regions to VFIO
From: |
Alex Williamson |
Subject: |
Re: question regarding QEMU adding overlapping memory regions to VFIO |
Date: |
Fri, 7 May 2021 09:42:05 -0600 |
On Fri, 7 May 2021 13:51:52 +0000
Thanos Makatos <thanos.makatos@nutanix.com> wrote:
> I've noticed that QEMU adds overlapping memory regions to VFIO, e.g.:
>
> vfio_listener_region_add_ram region_add [ram] 0xc0000 - 0xc0fff
> [0x7f6702c00000]
> vfio_listener_region_del region_del 0xc4000 - 0xdffff
> vfio_listener_region_add_ram region_add [ram] 0xc1000 - 0xc3fff
> [0x7f66406c1000]
> vfio_listener_region_del region_del 0xe0000 - 0xfffff
> vfio_listener_region_add_ram region_add [ram] 0xc4000 - 0xdffff
> [0x7f6702c04000]
> vfio_listener_region_add_ram region_add [ram] 0xc0000 - 0xc0fff
> [0x7f66406c0000]
> 2021-05-05T09:38:16.158864Z qemu-system-x86_64: vfio_dma_map(0x557b8fd281b0,
> 0xc0000, 0x1000, 0x7f66406c0000) = -22 (Resource temporarily unavailable)
>
> Region 0xc0000 - 0xc0fff is added first and then region 0xc0000 -
> 0xc0fff is added again? Is this legitimate? What is the implication
> of this? Is the previous region replaced by the more recent one?
This might be where the hack we have in hw/vfio/common.c:vfio_dma_map()
comes from:
/*
* 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 VGA ROM space.
*/
if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 ||
(errno == EBUSY && vfio_dma_unmap(container, iova, size, NULL) == 0 &&
ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0)) {
return 0;
}
Clearly that's only triggered with -EBUSY and you're getting -EINVAL,
did we unintentionally change the errno for this? What's the host
kernel version?
It's my expectation that this really shouldn't happen, the above is a
lazy workaround, but a listener being told to map two different things
at the same address range without an unmap in between seems like it
should violate the MemoryListener protocol. Thanks,
Alex