public inbox for drm-ai-reviews@public-inbox.freedesktop.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@nvidia.com>
Cc: Christian Koenig <christian.koenig@amd.com>,
	Dongwon Kim <dongwon.kim@intel.com>,
	dri-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
	iommu@lists.linux.dev, Kevin Tian <kevin.tian@intel.com>,
	Leon Romanovsky <leonro@nvidia.com>,
	linaro-mm-sig@lists.linaro.org, linux-media@vger.kernel.org,
	Matthew Brost <matthew.brost@intel.com>,
	Simona Vetter <simona.vetter@ffwll.ch>,
	Sumit Semwal <sumit.semwal@linaro.org>,
	Thomas Hellstrom <thomas.hellstrom@linux.intel.com>,
	Vivek Kasireddy <vivek.kasireddy@intel.com>
Subject: [PATCH RFC 25/26] iommufd/selftest: Check multi-phys DMA-buf scenarios
Date: Tue, 17 Feb 2026 20:11:56 -0400	[thread overview]
Message-ID: <25-v1-b5cab63049c0+191af-dmabuf_map_type_jgg@nvidia.com> (raw)
In-Reply-To: <0-v1-b5cab63049c0+191af-dmabuf_map_type_jgg@nvidia.com>

Improve the mock DMA-buf to have multiple physical ranges and add a
method to compare the values loaded into the iommu_domain with the
allocated page array.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
---
 drivers/iommu/iommufd/iommufd_test.h          |   7 ++
 drivers/iommu/iommufd/selftest.c              | 107 +++++++++++++++---
 tools/testing/selftests/iommu/iommufd.c       |  43 +++++++
 tools/testing/selftests/iommu/iommufd_utils.h |  17 +++
 4 files changed, 160 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index 73e73e1ec15837..dae7d808b7bade 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -31,6 +31,7 @@ enum {
 	IOMMU_TEST_OP_PASID_CHECK_HWPT,
 	IOMMU_TEST_OP_DMABUF_GET,
 	IOMMU_TEST_OP_DMABUF_REVOKE,
+	IOMMU_TEST_OP_MD_CHECK_DMABUF,
 };
 
 enum {
@@ -194,6 +195,12 @@ struct iommu_test_cmd {
 			__s32 dmabuf_fd;
 			__u32 revoked;
 		} dmabuf_revoke;
+		struct {
+			__s32 dmabuf_fd;
+			__aligned_u64 iova;
+			__aligned_u64 length;
+			__aligned_u64 offset;
+		} check_dmabuf;
 	};
 	__u32 last;
 };
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index 06820a50d5d24c..e924281840a07e 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -1957,16 +1957,19 @@ void iommufd_selftest_destroy(struct iommufd_object *obj)
 }
 
 struct iommufd_test_dma_buf {
-	void *memory;
 	size_t length;
+	unsigned int npages;
 	bool revoked;
+	struct page *pages[] __counted_by(npages);
 };
 
 static void iommufd_test_dma_buf_release(struct dma_buf *dmabuf)
 {
 	struct iommufd_test_dma_buf *priv = dmabuf->priv;
+	unsigned int i;
 
-	kfree(priv->memory);
+	for (i = 0; i < priv->npages; i++)
+		__free_page(priv->pages[i]);
 	kfree(priv);
 }
 
@@ -1981,19 +1984,22 @@ iommufd_dma_pal_map_phys(struct dma_buf_attachment *attachment)
 	if (priv->revoked)
 		return ERR_PTR(-ENODEV);
 
-	phys = kvmalloc(struct_size(phys, phys, 1), GFP_KERNEL);
+	phys = kvmalloc(struct_size(phys, phys, priv->npages), GFP_KERNEL);
 	if (!phys)
 		return ERR_PTR(-ENOMEM);
 
-	phys->length = 1;
-	phys->phys[0].paddr = virt_to_phys(priv->memory);
-	phys->phys[0].len = priv->length;
+	phys->length = priv->npages;
+	for (unsigned int i = 0; i < priv->npages; i++) {
+		phys->phys[i].paddr = page_to_phys(priv->pages[i]);
+		phys->phys[i].len = PAGE_SIZE;
+	}
 	return phys;
 }
 
 static void iommufd_dma_pal_unmap_phys(struct dma_buf_attachment *attach,
 				       struct dma_buf_phys_list *phys)
 {
+	kfree(phys);
 }
 
 static const struct dma_buf_mapping_pal_exp_ops iommufd_test_dma_buf_pal_ops = {
@@ -2022,21 +2028,27 @@ static int iommufd_test_dmabuf_get(struct iommufd_ucmd *ucmd,
 	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
 	struct iommufd_test_dma_buf *priv;
 	struct dma_buf *dmabuf;
+	size_t i;
 	int rc;
 
-	len = ALIGN(len, PAGE_SIZE);
-	if (len == 0 || len > PAGE_SIZE * 512)
+	unsigned int npages;
+
+	if (len == 0 || len % PAGE_SIZE || len > PAGE_SIZE * 512)
 		return -EINVAL;
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	npages = len >> PAGE_SHIFT;
+	priv = kzalloc(struct_size(priv, pages, npages), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
 	priv->length = len;
-	priv->memory = kzalloc(len, GFP_KERNEL);
-	if (!priv->memory) {
-		rc = -ENOMEM;
-		goto err_free;
+	priv->npages = npages;
+	for (i = 0; i < npages; i++) {
+		priv->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
+		if (!priv->pages[i]) {
+			rc = -ENOMEM;
+			goto err_free;
+		}
 	}
 
 	exp_info.ops = &iommufd_test_dmabuf_ops;
@@ -2053,7 +2065,11 @@ static int iommufd_test_dmabuf_get(struct iommufd_ucmd *ucmd,
 	return dma_buf_fd(dmabuf, open_flags);
 
 err_free:
-	kfree(priv->memory);
+	for (unsigned int i = 0; i < npages; i++) {
+		if (!priv->pages[i])
+			break;
+		__free_page(priv->pages[i]);
+	}
 	kfree(priv);
 	return rc;
 }
@@ -2085,6 +2101,64 @@ static int iommufd_test_dmabuf_revoke(struct iommufd_ucmd *ucmd, int fd,
 	return rc;
 }
 
+static int iommufd_test_md_check_dmabuf(struct iommufd_ucmd *ucmd,
+					unsigned int mockpt_id, int dmabuf_fd,
+					unsigned long iova, size_t length,
+					unsigned long offset)
+{
+	struct iommufd_hw_pagetable *hwpt;
+	struct iommufd_test_dma_buf *priv;
+	struct mock_iommu_domain *mock;
+	struct dma_buf *dmabuf;
+	unsigned int page_size;
+	unsigned long end;
+	size_t i;
+	int rc;
+
+	hwpt = get_md_pagetable(ucmd, mockpt_id, &mock);
+	if (IS_ERR(hwpt))
+		return PTR_ERR(hwpt);
+
+	dmabuf = dma_buf_get(dmabuf_fd);
+	if (IS_ERR(dmabuf)) {
+		rc = PTR_ERR(dmabuf);
+		goto out_put_hwpt;
+	}
+
+	if (dmabuf->ops != &iommufd_test_dmabuf_ops) {
+		rc = -EINVAL;
+		goto out_put_dmabuf;
+	}
+
+	priv = dmabuf->priv;
+	page_size = 1 << __ffs(mock->domain.pgsize_bitmap);
+	if (iova % page_size || length % page_size || offset % page_size ||
+	    check_add_overflow(offset, length, &end) || end > priv->length) {
+		rc = -EINVAL;
+		goto out_put_dmabuf;
+	}
+
+	for (i = 0; i < length; i += page_size) {
+		phys_addr_t expected =
+			page_to_phys(priv->pages[(offset + i) / PAGE_SIZE]) +
+			((offset + i) % PAGE_SIZE);
+		phys_addr_t io_phys =
+			mock->domain.ops->iova_to_phys(&mock->domain, iova + i);
+
+		if (io_phys != expected) {
+			rc = -EINVAL;
+			goto out_put_dmabuf;
+		}
+	}
+	rc = 0;
+
+out_put_dmabuf:
+	dma_buf_put(dmabuf);
+out_put_hwpt:
+	iommufd_put_object(ucmd->ictx, &hwpt->obj);
+	return rc;
+}
+
 int iommufd_test(struct iommufd_ucmd *ucmd)
 {
 	struct iommu_test_cmd *cmd = ucmd->cmd;
@@ -2170,6 +2244,11 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
 		return iommufd_test_dmabuf_revoke(ucmd,
 						  cmd->dmabuf_revoke.dmabuf_fd,
 						  cmd->dmabuf_revoke.revoked);
+	case IOMMU_TEST_OP_MD_CHECK_DMABUF:
+		return iommufd_test_md_check_dmabuf(
+			ucmd, cmd->id, cmd->check_dmabuf.dmabuf_fd,
+			cmd->check_dmabuf.iova, cmd->check_dmabuf.length,
+			cmd->check_dmabuf.offset);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index dadad277f4eb2e..2673f9f153392f 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -1580,10 +1580,53 @@ TEST_F(iommufd_ioas, dmabuf_simple)
 	test_err_ioctl_ioas_map_file(EINVAL, dfd, buf_size, buf_size, &iova);
 	test_err_ioctl_ioas_map_file(EINVAL, dfd, 0, buf_size + 1, &iova);
 	test_ioctl_ioas_map_file(dfd, 0, buf_size, &iova);
+	if (variant->mock_domains)
+		test_cmd_check_dmabuf(self->hwpt_id, dfd, iova, buf_size, 0);
 
 	close(dfd);
 }
 
+TEST_F(iommufd_ioas, dmabuf_multi_page)
+{
+	__u64 iova;
+	int dfd;
+
+	/* Single page */
+	test_cmd_get_dmabuf(PAGE_SIZE, &dfd);
+	test_ioctl_ioas_map_file(dfd, 0, PAGE_SIZE, &iova);
+	if (variant->mock_domains)
+		test_cmd_check_dmabuf(self->hwpt_id, dfd, iova, PAGE_SIZE, 0);
+	close(dfd);
+
+	/* Many pages - exercises batch filling across multiple phys entries */
+	test_cmd_get_dmabuf(PAGE_SIZE * 64, &dfd);
+	test_ioctl_ioas_map_file(dfd, 0, PAGE_SIZE * 64, &iova);
+	if (variant->mock_domains)
+		test_cmd_check_dmabuf(self->hwpt_id, dfd, iova, PAGE_SIZE * 64,
+				      0);
+	close(dfd);
+
+	/* Sub-range from the middle - exercises seeking into the phys array */
+	test_cmd_get_dmabuf(PAGE_SIZE * 16, &dfd);
+	test_ioctl_ioas_map_file(dfd, PAGE_SIZE * 4, PAGE_SIZE * 8, &iova);
+	if (variant->mock_domains)
+		test_cmd_check_dmabuf(self->hwpt_id, dfd, iova, PAGE_SIZE * 8,
+				      PAGE_SIZE * 4);
+	close(dfd);
+
+	/* Multiple sub-ranges from the same dmabuf */
+	test_cmd_get_dmabuf(PAGE_SIZE * 16, &dfd);
+	test_ioctl_ioas_map_file(dfd, 0, PAGE_SIZE * 4, &iova);
+	if (variant->mock_domains)
+		test_cmd_check_dmabuf(self->hwpt_id, dfd, iova, PAGE_SIZE * 4,
+				      0);
+	test_ioctl_ioas_map_file(dfd, PAGE_SIZE * 8, PAGE_SIZE * 4, &iova);
+	if (variant->mock_domains)
+		test_cmd_check_dmabuf(self->hwpt_id, dfd, iova, PAGE_SIZE * 4,
+				      PAGE_SIZE * 8);
+	close(dfd);
+}
+
 TEST_F(iommufd_ioas, dmabuf_revoke)
 {
 	size_t buf_size = PAGE_SIZE*4;
diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
index 5502751d500c89..35fd91d354f998 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -593,6 +593,23 @@ static int _test_cmd_revoke_dmabuf(int fd, int dmabuf_fd, bool revoked)
 #define test_cmd_revoke_dmabuf(dmabuf_fd, revoke) \
 	ASSERT_EQ(0, _test_cmd_revoke_dmabuf(self->fd, dmabuf_fd, revoke))
 
+#define test_cmd_check_dmabuf(_hwpt_id, _dmabuf_fd, _iova, _length, _offset) \
+	({                                                                   \
+		struct iommu_test_cmd check_cmd = {                          \
+			.size = sizeof(check_cmd),                           \
+			.op = IOMMU_TEST_OP_MD_CHECK_DMABUF,                 \
+			.id = _hwpt_id,                                      \
+			.check_dmabuf = { .dmabuf_fd = _dmabuf_fd,           \
+					  .iova = _iova,                     \
+					  .length = _length,                 \
+					  .offset = _offset },               \
+		};                                                           \
+		ASSERT_EQ(0, ioctl(self->fd,                                 \
+				   _IOMMU_TEST_CMD(                          \
+					   IOMMU_TEST_OP_MD_CHECK_DMABUF),   \
+				   &check_cmd));                             \
+	})
+
 static int _test_ioctl_destroy(int fd, unsigned int id)
 {
 	struct iommu_destroy cmd = {
-- 
2.43.0


  parent reply	other threads:[~2026-02-18  0:12 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-18  0:11 [PATCH RFC 00/26] Add DMA-buf mapping types and convert vfio/iommufd to use them Jason Gunthorpe
2026-02-18  0:11 ` [PATCH RFC 01/26] dma-buf: Introduce DMA-buf mapping types Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 02/26] dma-buf: Add the SGT DMA mapping type Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 03/26] dma-buf: Add dma_buf_mapping_attach() Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 04/26] dma-buf: Route SGT related actions through attach->map_type Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 05/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 06/26] drm: Check the SGT ops for drm_gem_map_dma_buf() Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 07/26] dma-buf: Convert all the simple exporters to use SGT mapping type Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 08/26] drm/vmwgfx: Use match_mapping instead of dummy calls Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 09/26] accel/habanalabs: Use the SGT mapping type Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 10/26] drm/xe/dma-buf: " Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 11/26] drm/amdgpu: " Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 12/26] vfio/pci: Change the DMA-buf exporter to use mapping_type Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 13/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT mapping type Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 14/26] iio: buffer: convert " Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 15/26] functionfs: " Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 16/26] dma-buf: Remove unused SGT stuff from the common structures Jason Gunthorpe
2026-02-18  1:37   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 17/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 18/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_* Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 19/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 20/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach() Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 21/26] dma-buf: Add the Physical Address List DMA mapping type Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 22/26] vfio/pci: Add physical address list support to DMABUF Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 23/26] iommufd: Use the PAL mapping type instead of a vfio function Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 24/26] iommufd: Support DMA-bufs with multiple physical ranges Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  0:11 ` Jason Gunthorpe [this message]
2026-02-18  1:38   ` Claude review: iommufd/selftest: Check multi-phys DMA-buf scenarios Claude Code Review Bot
2026-02-18  0:11 ` [PATCH RFC 26/26] dma-buf: Add kunit tests for mapping type Jason Gunthorpe
2026-02-18  1:38   ` Claude review: " Claude Code Review Bot
2026-02-18  1:37 ` Claude review: Add DMA-buf mapping types and convert vfio/iommufd to use them Claude Code Review Bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=25-v1-b5cab63049c0+191af-dmabuf_map_type_jgg@nvidia.com \
    --to=jgg@nvidia.com \
    --cc=christian.koenig@amd.com \
    --cc=dongwon.kim@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=iommu@lists.linux.dev \
    --cc=kevin.tian@intel.com \
    --cc=leonro@nvidia.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-media@vger.kernel.org \
    --cc=matthew.brost@intel.com \
    --cc=simona.vetter@ffwll.ch \
    --cc=sumit.semwal@linaro.org \
    --cc=thomas.hellstrom@linux.intel.com \
    --cc=vivek.kasireddy@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox