summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2015-02-10 10:25:44 -0700
committerAlex Williamson <alex.williamson@redhat.com>2015-02-10 10:25:44 -0700
commit2e6e697e166568fdd09ceaa8c7c8c8c53a5e345b (patch)
tree6c3d5891b0522b6e204ea779b418d193c9416a66
parentba5e6bfa1aee29a8f72c5538c565dfb9889cf273 (diff)
downloadqemu-2e6e697e166568fdd09ceaa8c7c8c8c53a5e345b.zip
vfio: Use vfio type1 v2 IOMMU interface
The difference between v1 and v2 is fairly subtle, simply more deterministic behavior for unmaps. The v1 interface allows the user to attempt to unmap sub-regions of previous mappings, returning success with zero size if unable to comply. This was a reflection of the underlying IOMMU API. The v2 interface requires that the user may only unmap fully contained mappings, ie. an unmap cannot intersect or bisect a previous mapping, but may cover multiple mappings. QEMU never made use of the sub-region v1 support anyway, so we can support either v1 or v2. We'll favor v2 since it's newer. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r--hw/vfio/common.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index b230ef102b..c5d15510dd 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -662,7 +662,10 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
container = g_malloc0(sizeof(*container));
container->space = space;
container->fd = fd;
- if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU)) {
+ if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU) ||
+ ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU)) {
+ bool v2 = !!ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_TYPE1v2_IOMMU);
+
ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd);
if (ret) {
error_report("vfio: failed to set group container: %m");
@@ -670,7 +673,8 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as)
goto free_container_exit;
}
- ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
+ ret = ioctl(fd, VFIO_SET_IOMMU,
+ v2 ? VFIO_TYPE1v2_IOMMU : VFIO_TYPE1_IOMMU);
if (ret) {
error_report("vfio: failed to set iommu for container: %m");
ret = -errno;