From: Nicolin Chen <nicolinc@nvidia.com>
To: Will Deacon <will@kernel.org>, Jason Gunthorpe <jgg@nvidia.com>,
"Kevin Tian" <kevin.tian@intel.com>,
Lu Baolu <baolu.lu@linux.intel.com>
Cc: Robin Murphy <robin.murphy@arm.com>, <joro@8bytes.org>,
David Woodhouse <dwmw2@infradead.org>,
<linux-arm-kernel@lists.infradead.org>, <iommu@lists.linux.dev>,
<linux-kernel@vger.kernel.org>
Subject: [PATCH v1 3/5] iommufd/selftest: Convert cache invalidation mocks to the core array loop
Date: Mon, 29 Jun 2026 14:15:38 -0700 [thread overview]
Message-ID: <0b590a04fe2d38d696d0e31e37d8afdb1b6725f2.1782767398.git.nicolinc@nvidia.com> (raw)
In-Reply-To: <cover.1782767398.git.nicolinc@nvidia.com>
The vIOMMU and the nested-domain selftest invalidation mocks each used to
walk the whole request array on their own, with the vIOMMU mock even
allocating a buffer sized to the entire array in order to do so first.
The iommufd core now iterates the request array itself and re-invokes the
op with the not-yet-handled sub-array, so handle just a single request per
call out of the front of that sub-array and report one handled entry via
the array->entry_num. Drop both of the loops and the kzalloc_objs() in the
viommu callback function, and keep returning a success for an empty array
as a probe of the selftest data type.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
---
drivers/iommu/iommufd/selftest.c | 147 +++++++++++++++----------------
1 file changed, 72 insertions(+), 75 deletions(-)
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index af07c642a5260..51da687e432ef 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -631,70 +631,63 @@ mock_viommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
static int mock_viommu_cache_invalidate(struct iommufd_viommu *viommu,
struct iommu_user_data_array *array)
{
- struct iommu_viommu_invalidate_selftest *cmds;
- struct iommu_viommu_invalidate_selftest *cur;
- struct iommu_viommu_invalidate_selftest *end;
- int rc;
+ struct iommu_viommu_invalidate_selftest cmd;
+ struct mock_dev *mdev;
+ struct device *dev;
+ u32 processed = 0;
+ int rc = 0;
+ int i;
- /* A zero-length array is allowed to validate the array type */
- if (array->entry_num == 0 &&
- array->type == IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST) {
- array->entry_num = 0;
- return 0;
+ if (array->type != IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST) {
+ rc = -EINVAL;
+ goto out;
}
- cmds = kzalloc_objs(*cmds, array->entry_num);
- if (!cmds)
- return -ENOMEM;
- cur = cmds;
- end = cmds + array->entry_num;
+ /*
+ * The core re-invokes this op for the remaining requests, so handle one
+ * request per call. A zero-length array only probes the type, validated
+ * above.
+ */
+ if (!array->entry_num)
+ goto out;
- static_assert(sizeof(*cmds) == 3 * sizeof(u32));
- rc = iommu_copy_struct_from_full_user_array(
- cmds, sizeof(*cmds), array,
- IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST);
+ rc = iommu_copy_struct_from_user_array(
+ &cmd, array, IOMMU_VIOMMU_INVALIDATE_DATA_SELFTEST, 0,
+ cache_id);
if (rc)
goto out;
- while (cur != end) {
- struct mock_dev *mdev;
- struct device *dev;
- int i;
-
- if (cur->flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- rc = -EOPNOTSUPP;
- goto out;
- }
-
- if (cur->cache_id > MOCK_DEV_CACHE_ID_MAX) {
- rc = -EINVAL;
- goto out;
- }
+ if (cmd.flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
- xa_lock(&viommu->vdevs);
- dev = iommufd_viommu_find_dev(viommu,
- (unsigned long)cur->vdev_id);
- if (!dev) {
- xa_unlock(&viommu->vdevs);
- rc = -EINVAL;
- goto out;
- }
- mdev = container_of(dev, struct mock_dev, dev);
+ if (cmd.cache_id > MOCK_DEV_CACHE_ID_MAX) {
+ rc = -EINVAL;
+ goto out;
+ }
- if (cur->flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- /* Invalidate all cache entries and ignore cache_id */
- for (i = 0; i < MOCK_DEV_CACHE_NUM; i++)
- mdev->cache[i] = 0;
- } else {
- mdev->cache[cur->cache_id] = 0;
- }
+ xa_lock(&viommu->vdevs);
+ dev = iommufd_viommu_find_dev(viommu, (unsigned long)cmd.vdev_id);
+ if (!dev) {
xa_unlock(&viommu->vdevs);
-
- cur++;
+ rc = -EINVAL;
+ goto out;
+ }
+ mdev = container_of(dev, struct mock_dev, dev);
+
+ if (cmd.flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ /* Invalidate all cache entries and ignore cache_id */
+ for (i = 0; i < MOCK_DEV_CACHE_NUM; i++)
+ mdev->cache[i] = 0;
+ } else {
+ mdev->cache[cmd.cache_id] = 0;
}
+ xa_unlock(&viommu->vdevs);
+
+ processed = 1;
out:
- array->entry_num = cur - cmds;
- kfree(cmds);
+ array->entry_num = processed;
return rc;
}
@@ -875,42 +868,46 @@ mock_domain_cache_invalidate_user(struct iommu_domain *domain,
struct mock_iommu_domain_nested *mock_nested = to_mock_nested(domain);
struct iommu_hwpt_invalidate_selftest inv;
u32 processed = 0;
- int i = 0, j;
int rc = 0;
+ int i;
if (array->type != IOMMU_HWPT_INVALIDATE_DATA_SELFTEST) {
rc = -EINVAL;
goto out;
}
- for ( ; i < array->entry_num; i++) {
- rc = iommu_copy_struct_from_user_array(&inv, array,
- IOMMU_HWPT_INVALIDATE_DATA_SELFTEST,
- i, iotlb_id);
- if (rc)
- break;
+ /*
+ * The core re-invokes this op for the remaining requests, so handle one
+ * request per call. A zero-length array only probes the type, validated
+ * above.
+ */
+ if (!array->entry_num)
+ goto out;
- if (inv.flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- rc = -EOPNOTSUPP;
- break;
- }
+ rc = iommu_copy_struct_from_user_array(
+ &inv, array, IOMMU_HWPT_INVALIDATE_DATA_SELFTEST, 0, iotlb_id);
+ if (rc)
+ goto out;
- if (inv.iotlb_id > MOCK_NESTED_DOMAIN_IOTLB_ID_MAX) {
- rc = -EINVAL;
- break;
- }
+ if (inv.flags & ~IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ rc = -EOPNOTSUPP;
+ goto out;
+ }
- if (inv.flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
- /* Invalidate all mock iotlb entries and ignore iotlb_id */
- for (j = 0; j < MOCK_NESTED_DOMAIN_IOTLB_NUM; j++)
- mock_nested->iotlb[j] = 0;
- } else {
- mock_nested->iotlb[inv.iotlb_id] = 0;
- }
+ if (inv.iotlb_id > MOCK_NESTED_DOMAIN_IOTLB_ID_MAX) {
+ rc = -EINVAL;
+ goto out;
+ }
- processed++;
+ if (inv.flags & IOMMU_TEST_INVALIDATE_FLAG_ALL) {
+ /* Invalidate all mock iotlb entries and ignore iotlb_id */
+ for (i = 0; i < MOCK_NESTED_DOMAIN_IOTLB_NUM; i++)
+ mock_nested->iotlb[i] = 0;
+ } else {
+ mock_nested->iotlb[inv.iotlb_id] = 0;
}
+ processed = 1;
out:
array->entry_num = processed;
return rc;
--
2.43.0
next prev parent reply other threads:[~2026-06-29 21:16 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 21:15 [PATCH v1 0/5] iommufd: Iterate the cache invalidation array in the core Nicolin Chen
2026-06-29 21:15 ` [PATCH v1 1/5] iommu/arm-smmu-v3-iommufd: Reject unsupported bits in invalidation commands Nicolin Chen
2026-07-03 6:20 ` Tian, Kevin
2026-07-03 8:00 ` Nicolin Chen
2026-07-06 17:16 ` Jason Gunthorpe
2026-07-06 17:46 ` Nicolin Chen
2026-06-29 21:15 ` [PATCH v1 2/5] iommufd: Iterate the cache invalidation array in the core Nicolin Chen
2026-07-03 6:21 ` Tian, Kevin
2026-06-29 21:15 ` Nicolin Chen [this message]
2026-07-03 6:22 ` [PATCH v1 3/5] iommufd/selftest: Convert cache invalidation mocks to the core array loop Tian, Kevin
2026-06-29 21:15 ` [PATCH v1 4/5] iommu/arm-smmu-v3-iommufd: Convert cache invalidation " Nicolin Chen
2026-07-03 6:30 ` Tian, Kevin
2026-06-29 21:15 ` [PATCH v1 5/5] iommu/vt-d: Convert nested " Nicolin Chen
2026-07-03 6:31 ` Tian, Kevin
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=0b590a04fe2d38d696d0e31e37d8afdb1b6725f2.1782767398.git.nicolinc@nvidia.com \
--to=nicolinc@nvidia.com \
--cc=baolu.lu@linux.intel.com \
--cc=dwmw2@infradead.org \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robin.murphy@arm.com \
--cc=will@kernel.org \
/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