The VFIO-PCI ioctl VFIO_DEVICE_FLAGS_PCI_MSIX_MMAP flag indicate that platform support mmapping MSI-X table.
With this flag set, we skip some MSI-X table check so that QEMU can mmap MSI-X table successfully. And we also raise the priority of mmap memory region in case of overlap with MSI-X/PBA memory region which is added in msix_init(). Signed-off-by: Yongji Xie <xyj...@linux.vnet.ibm.com> --- hw/vfio/pci.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index a7c6171..bec301c 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -1339,7 +1339,8 @@ static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled) } memory_region_set_enabled(&bar->region.mmap_mem, enabled); - if (vdev->msix && vdev->msix->table_bar == i) { + if (vdev->msix && vdev->msix->table_bar == i && + !(vdev->vbasedev.flags & VFIO_DEVICE_FLAGS_PCI_MSIX_MMAP)) { memory_region_set_enabled(&vdev->msix->mmap_mem, enabled); } } @@ -1357,7 +1358,8 @@ static void vfio_unregister_bar(VFIOPCIDevice *vdev, int nr) memory_region_del_subregion(&bar->region.mem, &bar->region.mmap_mem); - if (vdev->msix && vdev->msix->table_bar == nr) { + if (vdev->msix && vdev->msix->table_bar == nr && + !(vdev->vbasedev.flags & VFIO_DEVICE_FLAGS_PCI_MSIX_MMAP)) { memory_region_del_subregion(&bar->region.mem, &vdev->msix->mmap_mem); } } @@ -1374,7 +1376,8 @@ static void vfio_unmap_bar(VFIOPCIDevice *vdev, int nr) munmap(bar->region.mmap, memory_region_size(&bar->region.mmap_mem)); - if (vdev->msix && vdev->msix->table_bar == nr) { + if (vdev->msix && vdev->msix->table_bar == nr && + !(vdev->vbasedev.flags & VFIO_DEVICE_FLAGS_PCI_MSIX_MMAP)) { munmap(vdev->msix->mmap, memory_region_size(&vdev->msix->mmap_mem)); } } @@ -1420,7 +1423,8 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr) * We can't mmap areas overlapping the MSIX vector table, so we * potentially insert a direct-mapped subregion before and after it. */ - if (vdev->msix && vdev->msix->table_bar == nr) { + if (vdev->msix && vdev->msix->table_bar == nr && + !(vdev->vbasedev.flags & VFIO_DEVICE_FLAGS_PCI_MSIX_MMAP)) { size = vdev->msix->table_offset & qemu_real_host_page_mask; } @@ -1429,9 +1433,14 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr) &bar->region.mmap_mem, &bar->region.mmap, size, 0, name)) { error_report("%s unsupported. Performance may be slow", name); + } else if (vdev->vbasedev.flags & VFIO_DEVICE_FLAGS_PCI_MSIX_MMAP) { + memory_region_del_subregion(&bar->region.mem, &bar->region.mmap_mem); + memory_region_add_subregion_overlap(&bar->region.mem, 0, + &bar->region.mmap_mem, 1); } - if (vdev->msix && vdev->msix->table_bar == nr) { + if (vdev->msix && vdev->msix->table_bar == nr && + !(vdev->vbasedev.flags & VFIO_DEVICE_FLAGS_PCI_MSIX_MMAP)) { uint64_t start; start = REAL_HOST_PAGE_ALIGN((uint64_t)vdev->msix->table_offset + -- 1.7.9.5