Skip to content

Commit afb4776

Browse files
committed
iommufd: Make vfio_compat's unmap succeed if the range is already empty
iommufd returns ENOENT when attempting to unmap a range that is already empty, while vfio type1 returns success. Fix vfio_compat to match. Fixes: d624d66 ("iommufd: vfio container FD ioctl compatibility") Link: https://patch.msgid.link/r/[email protected] Reviewed-by: Nicolin Chen <[email protected]> Reviewed-by: Alex Mastro <[email protected]> Reported-by: Alex Mastro <[email protected]> Closes: https://lore.kernel.org/r/[email protected] Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent b09ed52 commit afb4776

3 files changed

Lines changed: 9 additions & 9 deletions

File tree

drivers/iommu/iommufd/io_pagetable.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,8 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
707707
struct iopt_area *area;
708708
unsigned long unmapped_bytes = 0;
709709
unsigned int tries = 0;
710-
int rc = -ENOENT;
710+
/* If there are no mapped entries then success */
711+
int rc = 0;
711712

712713
/*
713714
* The domains_rwsem must be held in read mode any time any area->pages
@@ -777,8 +778,6 @@ static int iopt_unmap_iova_range(struct io_pagetable *iopt, unsigned long start,
777778

778779
down_write(&iopt->iova_rwsem);
779780
}
780-
if (unmapped_bytes)
781-
rc = 0;
782781

783782
out_unlock_iova:
784783
up_write(&iopt->iova_rwsem);
@@ -815,13 +814,8 @@ int iopt_unmap_iova(struct io_pagetable *iopt, unsigned long iova,
815814

816815
int iopt_unmap_all(struct io_pagetable *iopt, unsigned long *unmapped)
817816
{
818-
int rc;
819-
820-
rc = iopt_unmap_iova_range(iopt, 0, ULONG_MAX, unmapped);
821817
/* If the IOVAs are empty then unmap all succeeds */
822-
if (rc == -ENOENT)
823-
return 0;
824-
return rc;
818+
return iopt_unmap_iova_range(iopt, 0, ULONG_MAX, unmapped);
825819
}
826820

827821
/* The caller must always free all the nodes in the allowed_iova rb_root. */

drivers/iommu/iommufd/ioas.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ int iommufd_ioas_unmap(struct iommufd_ucmd *ucmd)
367367
&unmapped);
368368
if (rc)
369369
goto out_put;
370+
if (!unmapped) {
371+
rc = -ENOENT;
372+
goto out_put;
373+
}
370374
}
371375

372376
cmd->length = unmapped;

tools/testing/selftests/iommu/iommufd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,6 +2638,8 @@ TEST_F(vfio_compat_mock_domain, map)
26382638
ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));
26392639
ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
26402640
ASSERT_EQ(BUFFER_SIZE, unmap_cmd.size);
2641+
/* Unmap of empty is success */
2642+
ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_UNMAP_DMA, &unmap_cmd));
26412643

26422644
/* UNMAP_FLAG_ALL requires 0 iova/size */
26432645
ASSERT_EQ(0, ioctl(self->fd, VFIO_IOMMU_MAP_DMA, &map_cmd));

0 commit comments

Comments
 (0)