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
next prev 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