Skip to contentSkip to conversation

vfio: Fixup uiommu sharing

PATCH New Alex Williamson 1 participant 1 message May 11, 2011 VFIO driver

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 vfio: Fixup uiommu sharing

When setting up a vfio device, we can either create a new iommu domain for each device, or use an iommu domain shared between multiple devices. In the first case, we open /dev/uiommu for each device and pass the new file descriptor for each device's VFIO_DOMAIN_SET ioctl. For the latter, we use a single file descriptor multiple times.

This doesn't currently work because the dma region list is tied to the instance of the vfio device file opening. This completely breaks any kind of page accounting or dma region tracking, and if one device is closed, the other is in bad shape.

Instead, manage the uiommu connection around VFIO_DOMAIN_{UN}SET. The first vfio device to set a domain will create a vfio_uiommu object and add it to a list, subsequent users trying to use the same domain will share the object, last one out does the cleanup. For virtual machine usage, this means we can now have a single iommu domain context persist across addition and removal of devices, so long as there's at least one device always attached.

---

Tom,

This is the thing that was confusing me the other day. I think the model below makes more sense, but it's entirely possible that I'm overlooking your usage model. Let me know. Thanks,

Alex

Note: patch against "vfio: Allow sub-ranges to be unmapped"

 drivers/vfio/vfio_dma.c     |  212 +++++++++++++++++++++++++------------------
 drivers/vfio/vfio_main.c    |   91 ++++++------------
 drivers/vfio/vfio_netlink.c |    2 
 drivers/vfio/vfio_sysfs.c   |    3 -
 include/linux/vfio.h        |   36 ++++---
 5 files changed, 177 insertions(+), 167 deletions(-)
drivers/vfio/vfio_dma.c +124 -88
index bf260e4..154ccb7 100644
@@ -42,6 +42,9 @@
 #include <linux/workqueue.h>
 #include <linux/vfio.h>
 
+static LIST_HEAD(vfio_uiommu_list);
+static DEFINE_MUTEX(vfio_uiommu_lock);
+
 struct vwork {
 	struct mm_struct *mm;
 	unsigned long npage;
@@ -97,77 +100,75 @@ static void vfio_lock_acct(unsigned long npage)
 
 /* Unmap DMA region */
 /* dgate must be held */
-static void vfio_dma_unmap(struct vfio_listener *listener, unsigned long iova,
+static void vfio_dma_unmap(struct vfio_uiommu *uiommu, unsigned long iova,
 			   unsigned long npage, struct page **pages, int rdwr)
 {
-	struct vfio_dev *vdev = listener->vdev;
 	unsigned long i;
 
 	for (i = 0; i < npage; i++, iova += PAGE_SIZE) {
-		uiommu_unmap(vdev->udomain, iova, 0);
+		uiommu_unmap(uiommu->udomain, iova, 0);
 		if (rdwr)
 			SetPageDirty(pages[i]);
 		put_page(pages[i]);
 	}
-	vdev->locked_pages -= npage;
+	uiommu->locked_pages -= npage;
 	vfio_lock_acct(-npage);
 }
 
 /* Unmap ALL DMA regions */
-void vfio_dma_unmapall(struct vfio_listener *listener)
+static void vfio_dma_unmapall(struct vfio_uiommu *uiommu)
 {
 	struct list_head *pos, *pos2;
 	struct dma_map_page *mlp;
 
-	mutex_lock(&listener->vdev->dgate);
-	list_for_each_safe(pos, pos2, &listener->dm_list) {
+	mutex_lock(&uiommu->dgate);
+	list_for_each_safe(pos, pos2, &uiommu->dm_list) {
 		mlp = list_entry(pos, struct dma_map_page, list);
-		vfio_dma_unmap(listener, mlp->daddr, mlp->npage,
+		vfio_dma_unmap(uiommu, mlp->daddr, mlp->npage,
 			       mlp->pages, mlp->rdwr);
 		list_del(&mlp->list);
 		vfree(mlp->pages);
 		kfree(mlp);
 	}
-	mutex_unlock(&listener->vdev->dgate);
+	mutex_unlock(&uiommu->dgate);
 }
 
 /* Map DMA region */
 /* dgate must be held */
-static int vfio_dma_map(struct vfio_listener *listener, unsigned long iova,
+static int vfio_dma_map(struct vfio_uiommu *uiommu, unsigned long iova,
 			unsigned long npage, struct page **pages, int rdwr)
 {
-	struct vfio_dev *vdev = listener->vdev;
 	unsigned long i;
 	int ret;
 
 	/* Verify pages are not already mapped */
 	for (i = 0; i < npage; i++)
-		if (uiommu_iova_to_phys(vdev->udomain, iova + i * PAGE_SIZE))
+		if (uiommu_iova_to_phys(uiommu->udomain, iova + i * PAGE_SIZE))
 			return -EBUSY;
 
 	for (i = 0; i < npage; i++, iova += PAGE_SIZE) {
-		ret = uiommu_map(vdev->udomain, iova,
+		ret = uiommu_map(uiommu->udomain, iova,
 				 page_to_phys(pages[i]), 0, rdwr);
 		if (!ret)
 			continue;
 
 		/* Back out mappings on error */
 		for (i--, iova -= PAGE_SIZE; i >= 0; i--, iova -= PAGE_SIZE)
-			uiommu_unmap(vdev->udomain, iova, 0);
+			uiommu_unmap(uiommu->udomain, iova, 0);
 		return ret;
 	}
-	vdev->locked_pages += npage;
+	uiommu->locked_pages += npage;
 	vfio_lock_acct(npage);
 	return 0;
 }
 
-static struct dma_map_page *vfio_find_dma(struct vfio_listener *listener,
+static struct dma_map_page *vfio_find_dma(struct vfio_uiommu *uiommu,
 					  dma_addr_t start, size_t size)
 {
 	struct list_head *pos;
 	struct dma_map_page *mlp;
 
-	list_for_each(pos, &listener->dm_list) {
+	list_for_each(pos, &uiommu->dm_list) {
 		mlp = list_entry(pos, struct dma_map_page, list);
 		if (!(mlp->daddr + (mlp->npage << PAGE_SHIFT) <= start ||
 		      mlp->daddr >= start + size))
@@ -176,13 +177,13 @@ static struct dma_map_page *vfio_find_dma(struct vfio_listener *listener,
 	return NULL;
 }
 
-static struct dma_map_page *vfio_find_vaddr(struct vfio_listener *listener,
+static struct dma_map_page *vfio_find_vaddr(struct vfio_uiommu *uiommu,
 					    unsigned long start, size_t size)
 {
 	struct list_head *pos;
 	struct dma_map_page *mlp;
 
-	list_for_each(pos, &listener->dm_list) {
+	list_for_each(pos, &uiommu->dm_list) {
 		mlp = list_entry(pos, struct dma_map_page, list);
 		if (!(mlp->vaddr + (mlp->npage << PAGE_SHIFT) <= start ||
 		      mlp->vaddr >= start + size))
@@ -191,7 +192,7 @@ static struct dma_map_page *vfio_find_vaddr(struct vfio_listener *listener,
 	return NULL;
 }
 
-int vfio_remove_dma_overlap(struct vfio_listener *listener, dma_addr_t start,
+int vfio_remove_dma_overlap(struct vfio_uiommu *uiommu, dma_addr_t start,
 			    size_t size, struct dma_map_page *mlp,
 			    size_t *remaining)
 {
@@ -202,7 +203,7 @@ int vfio_remove_dma_overlap(struct vfio_listener *listener, dma_addr_t start,
 	/* Existing dma region is completely covered, unmap all */
 	if (start <= mlp->daddr &&
 	    start + size >= mlp->daddr + (mlp->npage << PAGE_SHIFT)) {
-		vfio_dma_unmap(listener, mlp->daddr, mlp->npage,
+		vfio_dma_unmap(uiommu, mlp->daddr, mlp->npage,
 			       mlp->pages, mlp->rdwr);
 		list_del(&mlp->list);
 		vfree(mlp->pages);
@@ -224,7 +225,7 @@ int vfio_remove_dma_overlap(struct vfio_listener *listener, dma_addr_t start,
 		if (!pages_hi)
 			return -ENOMEM;
 
-		vfio_dma_unmap(listener, mlp->daddr, npage_lo,
+		vfio_dma_unmap(uiommu, mlp->daddr, npage_lo,
 			       mlp->pages, mlp->rdwr);
 		mlp->daddr += overlap;
 		mlp->vaddr += overlap;
@@ -250,7 +251,7 @@ int vfio_remove_dma_overlap(struct vfio_listener *listener, dma_addr_t start,
 		if (!pages_lo)
 			return -ENOMEM;
 
-		vfio_dma_unmap(listener, start, npage_hi,
+		vfio_dma_unmap(uiommu, start, npage_hi,
 			       &mlp->pages[npage_lo], mlp->rdwr);
 		mlp->npage -= npage_hi;
 		memcpy(pages_lo, mlp->pages,
@@ -283,7 +284,7 @@ int vfio_remove_dma_overlap(struct vfio_listener *listener, dma_addr_t start,
 		return -ENOMEM;
 	}
 
-	vfio_dma_unmap(listener, start, size >> PAGE_SHIFT,
+	vfio_dma_unmap(uiommu, start, size >> PAGE_SHIFT,
 		       &mlp->pages[npage_lo], mlp->rdwr);
 
 	memcpy(pages_lo, mlp->pages, npage_lo * sizeof(struct page *));
@@ -299,13 +300,13 @@ int vfio_remove_dma_overlap(struct vfio_listener *listener, dma_addr_t start,
 	split->daddr = start + size;
 	split->vaddr = mlp->vaddr + (npage_lo << PAGE_SHIFT) + size;
 	split->rdwr = mlp->rdwr;
-	list_add(&split->list, &listener->dm_list);
+	list_add(&split->list, &uiommu->dm_list);
 	if (remaining)
 		*remaining -= size;
 	return 0;
 }
 
-int vfio_dma_unmap_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
+int vfio_dma_unmap_dm(struct vfio_uiommu *uiommu, struct vfio_dma_map *dmp)
 {
 	struct dma_map_page *mlp;
 	int ret = 0;
@@ -316,18 +317,18 @@ int vfio_dma_unmap_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
 	if (size & (PAGE_SIZE-1))
 		return -EINVAL;
 
-	if (!listener->vdev->udomain)
+	if (!uiommu)
 		return -EINVAL;
 
-	mutex_lock(&listener->vdev->dgate);
+	mutex_lock(&uiommu->dgate);
 	while (size &&
-	       (mlp = vfio_find_dma(listener, dmp->dmaaddr, dmp->size))) {
-		ret = vfio_remove_dma_overlap(listener, dmp->dmaaddr,
+	       (mlp = vfio_find_dma(uiommu, dmp->dmaaddr, dmp->size))) {
+		ret = vfio_remove_dma_overlap(uiommu, dmp->dmaaddr,
 					      dmp->size, mlp, &size);
 		if (ret)
 			break;
 	}
-	mutex_unlock(&listener->vdev->dgate);
+	mutex_unlock(&uiommu->dgate);
 	return ret;
 }
 
@@ -338,16 +339,16 @@ int vfio_dma_unmap_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
 static void vfio_dma_handle_mmu_notify(struct mmu_notifier *mn,
 		unsigned long start, unsigned long end)
 {
-	struct vfio_listener *listener;
+	struct vfio_uiommu *uiommu;
 	struct dma_map_page *mlp;
 
-	listener = container_of(mn, struct vfio_listener, mmu_notifier);
-	mutex_lock(&listener->vdev->dgate);
+	uiommu = container_of(mn, struct vfio_uiommu, mmu_notifier);
+	mutex_lock(&uiommu->dgate);
 
 	/* vaddrs are not unique (multiple daddrs could be mapped to the
 	 * same vaddr), therefore we have to search to exhaustion rather
 	 * than tracking how much we've unmapped. */
-	while ((mlp = vfio_find_vaddr(listener, start, end - start))) {
+	while ((mlp = vfio_find_vaddr(uiommu, start, end - start))) {
 		dma_addr_t dma_start;
 		int ret;
 
@@ -356,7 +357,7 @@ static void vfio_dma_handle_mmu_notify(struct mmu_notifier *mn,
 			dma_start -= mlp->vaddr - start;
 		else
 			dma_start += start - mlp->vaddr;
-		ret = vfio_remove_dma_overlap(listener, dma_start,
+		ret = vfio_remove_dma_overlap(uiommu, dma_start,
 					      end - start, mlp, NULL);
 		if (ret) {
 			printk(KERN_ERR "%s: "
@@ -365,7 +366,7 @@ static void vfio_dma_handle_mmu_notify(struct mmu_notifier *mn,
 			break;
 		}
 	}
-	mutex_unlock(&listener->vdev->dgate);
+	mutex_unlock(&uiommu->dgate);
 }
 
 static void vfio_dma_inval_page(struct mmu_notifier *mn,
@@ -386,9 +387,8 @@ static const struct mmu_notifier_ops vfio_dma_mmu_notifier_ops = {
 };
 #endif	/* CONFIG_MMU_NOTIFIER */
 
-int vfio_dma_map_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
+int vfio_dma_map_dm(struct vfio_uiommu *uiommu, struct vfio_dma_map *dmp)
 {
-	struct vfio_dev *vdev = listener->vdev;
 	int locked, lock_limit;
 	struct page **pages;
 	struct dma_map_page *mlp, *nmlp, *mmlp = NULL;
@@ -409,17 +409,17 @@ int vfio_dma_map_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
 	if (!npage)
 		return -EINVAL;
 
-	if (!vdev->udomain)
+	if (!uiommu)
 		return -EINVAL;
 
 	if (dmp->flags & VFIO_FLAG_WRITE)
 		rdwr |= IOMMU_WRITE;
-	if (vdev->cachec)
+	if (uiommu->cachec)
 		rdwr |= IOMMU_CACHE;
 
-	mutex_lock(&listener->vdev->dgate);
+	mutex_lock(&uiommu->dgate);
 
-	if (vfio_find_dma(listener, daddr, size)) {
+	if (vfio_find_dma(uiommu, daddr, size)) {
 		ret = -EBUSY;
 		goto out_lock;
 	}
@@ -433,23 +433,6 @@ int vfio_dma_map_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
 		ret = -ENOMEM;
 		goto out_lock;
 	}
-	/* only 1 address space per fd */
-	if (current->mm != listener->mm) {
-		if (listener->mm) {
-			ret = -EINVAL;
-			goto out_lock;
-		}
-		listener->mm = current->mm;
-#ifdef CONFIG_MMU_NOTIFIER
-		listener->mmu_notifier.ops = &vfio_dma_mmu_notifier_ops;
-		ret = mmu_notifier_register(&listener->mmu_notifier,
-						listener->mm);
-		if (ret)
-			printk(KERN_ERR "%s: mmu_notifier_register failed %d\n",
-				__func__, ret);
-		ret = 0;
-#endif
-	}
 
 	/* Allocate a new mlp, this may not be used if we merge, but
 	 * ENOMEM is easier to handle before we do the iova mapping */
@@ -478,7 +461,7 @@ int vfio_dma_map_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
 		goto out_lock;
 	}
 
-	ret = vfio_dma_map(listener, daddr, npage, pages, rdwr);
+	ret = vfio_dma_map(uiommu, daddr, npage, pages, rdwr);
 	if (ret) {
 		while (npage--)
 			put_page(pages[npage]);
@@ -489,7 +472,7 @@ int vfio_dma_map_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
 
 	/* Check if we abut a region below */
 	if (daddr) {
-		mlp = vfio_find_dma(listener, daddr - 1, 1);
+		mlp = vfio_find_dma(uiommu, daddr - 1, 1);
 		if (mlp && mlp->rdwr == rdwr &&
 		    mlp->vaddr + (mlp->npage << PAGE_SHIFT) == vaddr) {
 			struct page **mpages;
@@ -521,7 +504,7 @@ int vfio_dma_map_dm(struct vfio_listener *listener, struct vfio_dma_map *dmp)
 	}
 
 	if (daddr + size) {
-		mlp = vfio_find_dma(listener, daddr + size, 1);
+		mlp = vfio_find_dma(uiommu, daddr + size, 1);
 		if (mlp && mlp->rdwr == rdwr && mlp->vaddr == vaddr + size) {
 			struct page **mpages;
 
@@ -558,56 +541,67 @@ no_merge:
 		nmlp->daddr = daddr;
 		nmlp->vaddr = vaddr;
 		nmlp->rdwr = rdwr;
-		list_add(&nmlp->list, &listener->dm_list);
+		list_add(&nmlp->list, &uiommu->dm_list);
 	} else
 		kfree(nmlp);
 
 out_lock:
-	mutex_unlock(&listener->vdev->dgate);
+	mutex_unlock(&uiommu->dgate);
 	return ret;
 }
 
-int vfio_domain_unset(struct vfio_listener *listener)
+int vfio_domain_unset(struct vfio_dev *vdev)
 {
-	struct vfio_dev *vdev = listener->vdev;
 	struct pci_dev *pdev = vdev->pdev;
+	struct uiommu_domain *udomain;
 
-	if (!vdev->udomain)
+	if (!vdev->uiommu)
 		return 0;
-	if (!list_empty(&listener->dm_list))
-		return -EBUSY;
-	uiommu_detach_device(vdev->udomain, &pdev->dev);
-	uiommu_put(vdev->udomain);
-	vdev->udomain = NULL;
+
+	udomain = vdev->uiommu->udomain;
+
+	mutex_lock(&vfio_uiommu_lock);
+	if (--vdev->uiommu->refcnt == 0) {
+#ifdef CONFIG_MMU_NOTIFIER
+		mmu_notifier_unregister(&vdev->uiommu->mmu_notifier,
+					vdev->uiommu->mm);
+#endif
+		vfio_dma_unmapall(vdev->uiommu);
+		list_del(&vdev->uiommu->next);
+		kfree(vdev->uiommu);
+	}
+	mutex_unlock(&vfio_uiommu_lock);
+
+	uiommu_detach_device(udomain, &pdev->dev);
+	uiommu_put(udomain);
+	vdev->uiommu = NULL;
 	return 0;
 }
 
-int vfio_domain_set(struct vfio_listener *listener, int fd, int unsafe_ok)
+int vfio_domain_set(struct vfio_dev *vdev, int fd, int unsafe_ok)
 {
-	struct vfio_dev *vdev = listener->vdev;
-	struct uiommu_domain *udomain;
 	struct pci_dev *pdev = vdev->pdev;
-	int ret;
-	int safe;
+	struct uiommu_domain *udomain;
+	struct list_head *pos;
+	struct vfio_uiommu *uiommu = NULL;
+	int ret, cachec, intremap = 0;
 
-	if (vdev->udomain)
+	if (vdev->uiommu)
 		return -EBUSY;
+
 	udomain = uiommu_fdget(fd);
 	if (IS_ERR(udomain))
 		return PTR_ERR(udomain);
 
-	safe = 0;
 #ifdef IOMMU_CAP_INTR_REMAP	/* >= 2.6.36 */
 	/* iommu domain must also isolate dev interrupts */
-	if (uiommu_domain_has_cap(udomain, IOMMU_CAP_INTR_REMAP))
-		safe = 1;
+	intremap = uiommu_domain_has_cap(udomain, IOMMU_CAP_INTR_REMAP);
 #endif
-	if (!safe && !unsafe_ok) {
+	if (!intremap && !unsafe_ok) {
 		printk(KERN_WARNING "%s: no interrupt remapping!\n", __func__);
 		return -EINVAL;
 	}
 
-	vfio_domain_unset(listener);
 	ret = uiommu_attach_device(udomain, &pdev->dev);
 	if (ret) {
 		printk(KERN_ERR "%s: attach_device failed %d\n",
@@ -615,8 +609,50 @@ int vfio_domain_set(struct vfio_listener *listener, int fd, int unsafe_ok)
 		uiommu_put(udomain);
 		return ret;
 	}
-	vdev->cachec = iommu_domain_has_cap(udomain->domain,
-				IOMMU_CAP_CACHE_COHERENCY);
-	vdev->udomain = udomain;
-	return 0;
+
+	cachec = iommu_domain_has_cap(udomain->domain,
+				      IOMMU_CAP_CACHE_COHERENCY);
+
+	mutex_lock(&vfio_uiommu_lock);
+	list_for_each(pos, &vfio_uiommu_list) {
+		uiommu = list_entry(pos, struct vfio_uiommu, next);
+		if (uiommu->udomain == udomain)
+			break;
+		uiommu = NULL;
+	}
+
+	if (!uiommu) {
+		uiommu = kzalloc(sizeof(*uiommu), GFP_KERNEL);
+		if (!uiommu) {
+			uiommu_detach_device(udomain, &pdev->dev);
+			uiommu_put(udomain);
+			ret = -ENOMEM;
+			goto out_lock;
+		}
+		uiommu->udomain = udomain;
+		uiommu->cachec = cachec;
+		uiommu->mm = current->mm;
+#ifdef CONFIG_MMU_NOTIFIER
+		uiommu->mmu_notifier.ops = &vfio_dma_mmu_notifier_ops;
+		ret = mmu_notifier_register(&uiommu->mmu_notifier, uiommu->mm);
+		if (ret)
+			printk(KERN_ERR "%s: mmu_notifier_register failed %d\n",
+				__func__, ret);
+		ret = 0;
+#endif
+		INIT_LIST_HEAD(&uiommu->dm_list);
+		mutex_init(&uiommu->dgate);
+		list_add(&uiommu->next, &vfio_uiommu_list);
+	} else if (uiommu->cachec != cachec || uiommu->mm != current->mm) {
+		uiommu_detach_device(udomain, &pdev->dev);
+		uiommu_put(udomain);
+		ret = -EINVAL;
+		goto out_lock;
+	}
+	uiommu->refcnt++;
+	mutex_unlock(&vfio_uiommu_lock);
+
+	vdev->uiommu = uiommu;
+out_lock:
+	return ret;
 }
drivers/vfio/vfio_main.c +31 -60

211 lines not on this page · raw message

drivers/vfio/vfio_netlink.c +1 -1
index 7a53e7b..063001e 100644
@@ -272,7 +272,7 @@ static int vfio_nl_pm_suspend_reply(struct sk_buff *skb, struct genl_info *info)
 	vdev = vfio_nl_get_vdev(info);
 	if (!vdev)
 		return -EINVAL;
-	if (vdev->listeners == 0)
+	if (vdev->refcnt == 0)
 		return -EINVAL;
 	vfio_pm_process_reply(value);
 	return 0;
drivers/vfio/vfio_sysfs.c +2 -1
index c6193fd..6b44096 100644
@@ -98,7 +98,8 @@ static ssize_t show_locked_pages(struct device *dev,
 
 	if (!vdev)
 		return -ENODEV;
-	return sprintf(buf, "%u\n", vdev->locked_pages);
+	return sprintf(buf, "%u\n", vdev->uiommu ?
+		       vdev->uiommu->locked_pages : 0);
 }
 
 static DEVICE_ATTR(locked_pages, S_IRUGO, show_locked_pages, NULL);
include/linux/vfio.h +19 -17
index a8b2405..74c156e 100644
@@ -42,6 +42,18 @@ struct vfio_nl_client {
 	u32			pid;
 };
 
+struct vfio_uiommu {
+	struct uiommu_domain	*udomain;
+	struct mutex		dgate;		/* dma op gate */
+	struct list_head	dm_list;
+	u32			locked_pages;
+	struct mm_struct	*mm;
+	struct mmu_notifier	mmu_notifier;
+	struct list_head	next;
+	int			refcnt;
+	int			cachec;
+};
+
 struct perm_bits;
 struct eoi_eventfd;
 struct vfio_dev {
@@ -53,10 +65,9 @@ struct vfio_dev {
 	int		devnum;
 	void __iomem	*barmap[PCI_STD_RESOURCE_END+1];
 	spinlock_t	irqlock;	/* guards command register accesses */
-	int		listeners;
-	u32		locked_pages;
-	struct mutex	lgate;		/* listener gate */
-	struct mutex	dgate;		/* dma op gate */
+	struct vfio_uiommu	*uiommu;
+	int		refcnt;
+	struct mutex	vgate;		/* device init/shutdown, refcnt gate */
 	struct mutex	igate;		/* intr op gate */
 	struct mutex	ngate;		/* netlink op gate */
 	struct list_head nlc_list;	/* netlink clients */
@@ -64,7 +75,6 @@ struct vfio_dev {
 	wait_queue_head_t nl_wait_q;
 	u32		nl_reply_seq;
 	u32		nl_reply_value;
-	struct uiommu_domain	*udomain;
 	int			cachec;
 	struct msix_entry	*msix;
 	struct eventfd_ctx	*ev_irq;
@@ -83,13 +93,6 @@ struct vfio_dev {
 	struct eoi_eventfd	*ev_eoi;
 };
 
-struct vfio_listener {
-	struct vfio_dev	*vdev;
-	struct list_head	dm_list;
-	struct mm_struct	*mm;
-	struct mmu_notifier	mmu_notifier;
-};
-
 /*
  * Structure for keeping track of memory nailed down by the
  * user for DMA
@@ -130,11 +133,10 @@ int vfio_setup_msix(struct vfio_dev *, int, int __user *);
 #endif
 
 struct vfio_dma_map;
-void vfio_dma_unmapall(struct vfio_listener *);
-int vfio_dma_unmap_dm(struct vfio_listener *, struct vfio_dma_map *);
-int vfio_dma_map_dm(struct vfio_listener *, struct vfio_dma_map *);
-int vfio_domain_set(struct vfio_listener *, int, int);
-int vfio_domain_unset(struct vfio_listener *);
+int vfio_dma_unmap_dm(struct vfio_uiommu *, struct vfio_dma_map *);
+int vfio_dma_map_dm(struct vfio_uiommu *, struct vfio_dma_map *);
+int vfio_domain_set(struct vfio_dev *, int, int);
+int vfio_domain_unset(struct vfio_dev *);
 
 int vfio_class_init(void);
 void vfio_class_destroy(void);