aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/vfio/common.c15
-rw-r--r--hw/vfio/pci.c9
-rw-r--r--include/hw/vfio/vfio-common.h1
3 files changed, 25 insertions, 0 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 07c03d78b6..5e84716218 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1471,6 +1471,21 @@ int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
return -ENODEV;
}
+bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type)
+{
+ struct vfio_region_info *info = NULL;
+ bool ret = false;
+
+ if (!vfio_get_region_info(vbasedev, region, &info)) {
+ if (vfio_get_region_info_cap(info, cap_type)) {
+ ret = true;
+ }
+ g_free(info);
+ }
+
+ return ret;
+}
+
/*
* Interfaces for IBM EEH (Enhanced Error Handling)
*/
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index b9d2c12b82..02974f4eb9 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1295,6 +1295,15 @@ static void vfio_pci_fixup_msix_region(VFIOPCIDevice *vdev)
VFIORegion *region = &vdev->bars[vdev->msix->table_bar].region;
/*
+ * If the host driver allows mapping of a MSIX data, we are going to
+ * do map the entire BAR and emulate MSIX table on top of that.
+ */
+ if (vfio_has_region_cap(&vdev->vbasedev, region->nr,
+ VFIO_REGION_INFO_CAP_MSIX_MAPPABLE)) {
+ return;
+ }
+
+ /*
* We expect to find a single mmap covering the whole BAR, anything else
* means it's either unsupported or already setup.
*/
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index c5efa32750..d9360148e6 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -193,6 +193,7 @@ int vfio_get_region_info(VFIODevice *vbasedev, int index,
struct vfio_region_info **info);
int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type,
uint32_t subtype, struct vfio_region_info **info);
+bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type);
#endif
extern const MemoryListener vfio_prereg_listener;