Add iommu_map_file() and __iommu_map_file() to map a file descriptor (such as a memfd or VFIO PCI dma-buf) into an iommufd IOAS via IOMMU_IOAS_MAP_FILE. Also skip regions without a host virtual address in __iommu_hva2iova(), since file-backed DMA mappings do not require one. Signed-off-by: David Matlack --- .../vfio/lib/include/libvfio/iommu.h | 9 ++++++ tools/testing/selftests/vfio/lib/iommu.c | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h b/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h index e9a3386a4719..2b39c49e66da 100644 --- a/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h +++ b/tools/testing/selftests/vfio/lib/include/libvfio/iommu.h @@ -42,6 +42,15 @@ static inline void iommu_map(struct iommu *iommu, struct dma_region *region) VFIO_ASSERT_EQ(__iommu_map(iommu, region), 0); } +int __iommu_map_file(struct iommu *iommu, int fd, u64 file_offset, + struct dma_region *region); + +static inline void iommu_map_file(struct iommu *iommu, int fd, u64 file_offset, + struct dma_region *region) +{ + VFIO_ASSERT_EQ(__iommu_map_file(iommu, fd, file_offset, region), 0); +} + int __iommu_unmap(struct iommu *iommu, struct dma_region *region, u64 *unmapped); static inline void iommu_unmap(struct iommu *iommu, struct dma_region *region) diff --git a/tools/testing/selftests/vfio/lib/iommu.c b/tools/testing/selftests/vfio/lib/iommu.c index b6f3c5c84e01..ba602685f892 100644 --- a/tools/testing/selftests/vfio/lib/iommu.c +++ b/tools/testing/selftests/vfio/lib/iommu.c @@ -71,6 +71,9 @@ int __iommu_hva2iova(struct iommu *iommu, void *vaddr, iova_t *iova) struct dma_region *region; list_for_each_entry(region, &iommu->dma_regions, link) { + if (!region->vaddr) + continue; + if (vaddr < region->vaddr) continue; @@ -149,6 +152,32 @@ int __iommu_map(struct iommu *iommu, struct dma_region *region) return 0; } +int __iommu_map_file(struct iommu *iommu, int fd, u64 file_offset, + struct dma_region *region) +{ + struct iommu_ioas_map_file args = { + .size = sizeof(args), + .flags = IOMMU_IOAS_MAP_READABLE | + IOMMU_IOAS_MAP_WRITEABLE | + IOMMU_IOAS_MAP_FIXED_IOVA, + .ioas_id = iommu->ioas_id, + .fd = fd, + .start = file_offset, + .length = region->size, + .iova = region->iova, + }; + + if (!iommu->iommufd) + return -EOPNOTSUPP; + + if (ioctl(iommu->iommufd, IOMMU_IOAS_MAP_FILE, &args)) + return -errno; + + list_add(®ion->link, &iommu->dma_regions); + + return 0; +} + static int __vfio_iommu_unmap(int fd, u64 iova, u64 size, u32 flags, u64 *unmapped) { struct vfio_iommu_type1_dma_unmap args = { -- 2.56.0.567.gdb80ae8cd5-goog