summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/iommufd/io_pagetable.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/iommufd/io_pagetable.c')
-rw-r--r--drivers/iommu/iommufd/io_pagetable.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c
index 756d347948f0..4f4a9d9aac57 100644
--- a/drivers/iommu/iommufd/io_pagetable.c
+++ b/drivers/iommu/iommufd/io_pagetable.c
@@ -458,6 +458,7 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
* is NULL. This prevents domain attach/detatch from running
* concurrently with cleaning up the area.
*/
+again:
down_read(&iopt->domains_rwsem);
down_write(&iopt->iova_rwsem);
while ((area = iopt_area_iter_first(iopt, start, last))) {
@@ -486,8 +487,11 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
area->prevent_access = true;
up_write(&iopt->iova_rwsem);
up_read(&iopt->domains_rwsem);
- /* Later patch calls back to drivers to unmap */
- return -EBUSY;
+ iommufd_access_notify_unmap(iopt, area_first,
+ iopt_area_length(area));
+ if (WARN_ON(READ_ONCE(area->num_accesses)))
+ return -EDEADLOCK;
+ goto again;
}
pages = area->pages;