diff options
author | Matthew Rosato | 2020-10-26 16:34:33 +0100 |
---|---|---|
committer | Alex Williamson | 2020-11-01 20:30:51 +0100 |
commit | 7486a62845b1e12011dd99973e4739f69d57cd38 (patch) | |
tree | 871c8f000b5b07a4230647b2bf807b5e5c79d2f8 /hw/vfio | |
parent | vfio: Create shared routine for scanning info capabilities (diff) | |
download | qemu-7486a62845b1e12011dd99973e4739f69d57cd38.tar.gz qemu-7486a62845b1e12011dd99973e4739f69d57cd38.tar.xz qemu-7486a62845b1e12011dd99973e4739f69d57cd38.zip |
vfio: Find DMA available capability
The underlying host may be limiting the number of outstanding DMA
requests for type 1 IOMMU. Add helper functions to check for the
DMA available capability and retrieve the current number of DMA
mappings allowed.
Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
[aw: vfio_get_info_dma_avail moved inside CONFIG_LINUX]
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'hw/vfio')
-rw-r--r-- | hw/vfio/common.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 693d3a2943..920786a23e 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -1149,6 +1149,37 @@ vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id) return vfio_get_cap((void *)info, info->cap_offset, id); } +static struct vfio_info_cap_header * +vfio_get_iommu_type1_info_cap(struct vfio_iommu_type1_info *info, uint16_t id) +{ + if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) { + return NULL; + } + + return vfio_get_cap((void *)info, info->cap_offset, id); +} + +bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, + unsigned int *avail) +{ + struct vfio_info_cap_header *hdr; + struct vfio_iommu_type1_info_dma_avail *cap; + + /* If the capability cannot be found, assume no DMA limiting */ + hdr = vfio_get_iommu_type1_info_cap(info, + VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL); + if (hdr == NULL) { + return false; + } + + if (avail != NULL) { + cap = (void *) hdr; + *avail = cap->avail; + } + + return true; +} + static int vfio_setup_region_sparse_mmaps(VFIORegion *region, struct vfio_region_info *info) { |