From: Jason Gunthorpe <jgg@nvidia.com>
To: iommu@lists.linux.dev, Kevin Tian <kevin.tian@intel.com>,
linux-kselftest@vger.kernel.org
Cc: kvm@vger.kernel.org, Nicolin Chen <nicolinc@nvidia.com>,
Yi Liu <yi.l.liu@intel.com>
Subject: [PATCH v2 14/17] iommufd/selftest: Test iommufd_device_replace()
Date: Tue, 7 Mar 2023 20:35:53 -0400 [thread overview]
Message-ID: <14-v2-51b9896e7862+8a8c-iommufd_alloc_jgg@nvidia.com> (raw)
In-Reply-To: <0-v2-51b9896e7862+8a8c-iommufd_alloc_jgg@nvidia.com>
From: Nicolin Chen <nicolinc@nvidia.com>
Allow the selftest to call the function on the mock idev, add some tests
to exercise it.
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
---
drivers/iommu/iommufd/iommufd_test.h | 4 ++
drivers/iommu/iommufd/selftest.c | 39 +++++++++++++++++++
include/linux/iommufd.h | 1 +
tools/testing/selftests/iommu/iommufd.c | 34 +++++++++++++++-
.../selftests/iommu/iommufd_fail_nth.c | 27 +++++++++++++
tools/testing/selftests/iommu/iommufd_utils.h | 28 +++++++++++++
6 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index b3d69cca77295c..e3f1035cbd6464 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -17,6 +17,7 @@ enum {
IOMMU_TEST_OP_ACCESS_PAGES,
IOMMU_TEST_OP_ACCESS_RW,
IOMMU_TEST_OP_SET_TEMP_MEMORY_LIMIT,
+ IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE,
};
enum {
@@ -52,6 +53,9 @@ struct iommu_test_cmd {
__u32 out_stdev_id;
__u32 out_hwpt_id;
} mock_domain;
+ struct {
+ __u32 pt_id;
+ } mock_domain_replace;
struct {
__aligned_u64 iova;
__aligned_u64 length;
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index 17cb7b95eb2757..866d77247a07fc 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -455,6 +455,42 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
return rc;
}
+/* Replace the mock domain with a manually allocated hw_pagetable */
+static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd,
+ unsigned int device_id, u32 pt_id,
+ struct iommu_test_cmd *cmd)
+{
+ struct iommufd_object *dev_obj;
+ struct selftest_obj *sobj;
+ int rc;
+
+ /*
+ * Prefer to use the OBJ_SELFTEST because the destroy_rwsem will ensure
+ * it doesn't race with detach, which is not allowed.
+ */
+ dev_obj =
+ iommufd_get_object(ucmd->ictx, device_id, IOMMUFD_OBJ_SELFTEST);
+ if (IS_ERR(dev_obj))
+ return PTR_ERR(dev_obj);
+
+ sobj = container_of(dev_obj, struct selftest_obj, obj);
+ if (sobj->type != TYPE_IDEV) {
+ rc = -EINVAL;
+ goto out_dev_obj;
+ }
+
+ rc = iommufd_device_replace(sobj->idev.idev, &pt_id);
+ if (rc)
+ goto out_dev_obj;
+
+ cmd->mock_domain_replace.pt_id = pt_id;
+ rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
+
+out_dev_obj:
+ iommufd_put_object(dev_obj);
+ return rc;
+}
+
/* Add an additional reserved IOVA to the IOAS */
static int iommufd_test_add_reserved(struct iommufd_ucmd *ucmd,
unsigned int mockpt_id,
@@ -939,6 +975,9 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
cmd->add_reserved.length);
case IOMMU_TEST_OP_MOCK_DOMAIN:
return iommufd_test_mock_domain(ucmd, cmd);
+ case IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE:
+ return iommufd_test_mock_domain_replace(
+ ucmd, cmd->id, cmd->mock_domain_replace.pt_id, cmd);
case IOMMU_TEST_OP_MD_CHECK_MAP:
return iommufd_test_md_check_pa(
ucmd, cmd->id, cmd->check_map.iova,
diff --git a/include/linux/iommufd.h b/include/linux/iommufd.h
index c0b5b3ac34f1e0..3044a432a83e22 100644
--- a/include/linux/iommufd.h
+++ b/include/linux/iommufd.h
@@ -22,6 +22,7 @@ struct iommufd_device *iommufd_device_bind(struct iommufd_ctx *ictx,
void iommufd_device_unbind(struct iommufd_device *idev);
int iommufd_device_attach(struct iommufd_device *idev, u32 *pt_id);
+int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id);
void iommufd_device_detach(struct iommufd_device *idev);
struct iommufd_access_ops {
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index da0443ba16830f..77b0601fd13a71 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -1001,6 +1001,7 @@ FIXTURE(iommufd_mock_domain)
uint32_t ioas_id;
uint32_t hwpt_id;
uint32_t hwpt_ids[2];
+ uint32_t stdev_ids[2];
int mmap_flags;
size_t mmap_buf_size;
};
@@ -1022,7 +1023,8 @@ FIXTURE_SETUP(iommufd_mock_domain)
ASSERT_GE(ARRAY_SIZE(self->hwpt_ids), variant->mock_domains);
for (i = 0; i != variant->mock_domains; i++)
- test_cmd_mock_domain(self->ioas_id, NULL, &self->hwpt_ids[i]);
+ test_cmd_mock_domain(self->ioas_id, &self->stdev_ids[i],
+ &self->hwpt_ids[i]);
self->hwpt_id = self->hwpt_ids[0];
self->mmap_flags = MAP_SHARED | MAP_ANONYMOUS;
@@ -1274,6 +1276,36 @@ TEST_F(iommufd_mock_domain, user_copy)
test_ioctl_destroy(ioas_id);
}
+TEST_F(iommufd_mock_domain, replace)
+{
+ uint32_t ioas_id;
+
+ test_ioctl_ioas_alloc(&ioas_id);
+
+ test_cmd_mock_domain_replace(self->stdev_ids[0], ioas_id);
+
+ /*
+ * Replacing the IOAS causes the prior HWPT to be deallocated, thus we
+ * should get enoent when we try to use it.
+ */
+ if (variant->mock_domains == 1)
+ test_err_mock_domain_replace(ENOENT, self->stdev_ids[0],
+ self->hwpt_ids[0]);
+
+ test_cmd_mock_domain_replace(self->stdev_ids[0], ioas_id);
+ if (variant->mock_domains >= 2) {
+ test_cmd_mock_domain_replace(self->stdev_ids[0],
+ self->hwpt_ids[1]);
+ test_cmd_mock_domain_replace(self->stdev_ids[0],
+ self->hwpt_ids[1]);
+ test_cmd_mock_domain_replace(self->stdev_ids[0],
+ self->hwpt_ids[0]);
+ }
+
+ test_cmd_mock_domain_replace(self->stdev_ids[0], self->ioas_id);
+ test_ioctl_destroy(ioas_id);
+}
+
/* VFIO compatibility IOCTLs */
TEST_F(iommufd, simple_ioctls)
diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
index d9afcb23810e1a..baaea15b355297 100644
--- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
+++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
@@ -569,4 +569,31 @@ TEST_FAIL_NTH(basic_fail_nth, access_pin_domain)
return 0;
}
+/* device.c */
+TEST_FAIL_NTH(basic_fail_nth, device)
+{
+ uint32_t ioas_id;
+ uint32_t ioas_id2;
+ uint32_t stdev_id;
+
+ self->fd = open("/dev/iommu", O_RDWR);
+ if (self->fd == -1)
+ return -1;
+
+ if (_test_ioctl_ioas_alloc(self->fd, &ioas_id))
+ return -1;
+
+ if (_test_ioctl_ioas_alloc(self->fd, &ioas_id2))
+ return -1;
+
+ fail_nth_enable();
+
+ if (_test_cmd_mock_domain(self->fd, ioas_id, &stdev_id, NULL))
+ return -1;
+
+ if (_test_cmd_mock_domain_replace(self->fd, stdev_id, ioas_id2, NULL))
+ return -1;
+ return 0;
+}
+
TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
index 85d6662ef8e867..3222f246600422 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -66,6 +66,34 @@ static int _test_cmd_mock_domain(int fd, unsigned int ioas_id, __u32 *stdev_id,
EXPECT_ERRNO(_errno, _test_cmd_mock_domain(self->fd, ioas_id, \
stdev_id, hwpt_id))
+static int _test_cmd_mock_domain_replace(int fd, __u32 stdev_id, __u32 pt_id,
+ __u32 *hwpt_id)
+{
+ struct iommu_test_cmd cmd = {
+ .size = sizeof(cmd),
+ .op = IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE,
+ .id = stdev_id,
+ .mock_domain_replace = {
+ .pt_id = pt_id,
+ },
+ };
+ int ret;
+
+ ret = ioctl(fd, IOMMU_TEST_CMD, &cmd);
+ if (ret)
+ return ret;
+ if (hwpt_id)
+ *hwpt_id = cmd.mock_domain_replace.pt_id;
+ return 0;
+}
+
+#define test_cmd_mock_domain_replace(stdev_id, pt_id) \
+ ASSERT_EQ(0, _test_cmd_mock_domain_replace(self->fd, stdev_id, pt_id, \
+ NULL))
+#define test_err_mock_domain_replace(_errno, stdev_id, pt_id) \
+ EXPECT_ERRNO(_errno, _test_cmd_mock_domain_replace(self->fd, stdev_id, \
+ pt_id, NULL))
+
static int _test_cmd_create_access(int fd, unsigned int ioas_id,
__u32 *access_id, unsigned int flags)
{
--
2.39.2
next prev parent reply other threads:[~2023-03-08 0:36 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-08 0:35 [PATCH v2 00/17] Add iommufd physical device operations for replace and alloc hwpt Jason Gunthorpe
2023-03-08 0:35 ` [PATCH v2 01/17] iommufd: Move isolated msi enforcement to iommufd_device_bind() Jason Gunthorpe
2023-03-08 2:55 ` Baolu Lu
2023-03-09 12:53 ` Jason Gunthorpe
2023-03-08 0:35 ` [PATCH v2 02/17] iommufd: Add iommufd_group Jason Gunthorpe
2023-03-08 3:18 ` Baolu Lu
2023-03-09 15:51 ` Jason Gunthorpe
2023-03-10 10:30 ` Tian, Kevin
2023-03-08 0:35 ` [PATCH v2 03/17] iommufd: Replace the hwpt->devices list with iommufd_group Jason Gunthorpe
2023-03-08 11:56 ` Baolu Lu
2023-03-10 10:36 ` Tian, Kevin
2023-03-10 14:16 ` Jason Gunthorpe
2023-03-08 0:35 ` [PATCH v2 04/17] iommu: Export iommu_get_resv_regions() Jason Gunthorpe
2023-03-08 12:06 ` Baolu Lu
2023-03-08 14:54 ` Jason Gunthorpe
2023-03-10 10:40 ` Tian, Kevin
2023-03-08 0:35 ` [PATCH v2 05/17] iommufd: Keep track of each device's reserved regions instead of groups Jason Gunthorpe
2023-03-08 12:32 ` Baolu Lu
2023-03-08 15:02 ` Jason Gunthorpe
2023-03-09 1:43 ` Baolu Lu
2023-03-10 10:42 ` Tian, Kevin
2023-03-08 0:35 ` [PATCH v2 06/17] iommufd: Use the iommufd_group to avoid duplicate MSI setup Jason Gunthorpe
2023-03-10 10:42 ` Tian, Kevin
2023-03-08 0:35 ` [PATCH v2 07/17] iommufd: Make sw_msi_start a group global Jason Gunthorpe
2023-03-10 10:45 ` Tian, Kevin
2023-03-08 0:35 ` [PATCH v2 08/17] iommufd: Move putting a hwpt to a helper function Jason Gunthorpe
2023-03-08 12:42 ` Baolu Lu
2023-03-10 10:45 ` Tian, Kevin
2023-03-08 0:35 ` [PATCH v2 09/17] iommufd: Add enforced_cache_coherency to iommufd_hw_pagetable_alloc() Jason Gunthorpe
2023-03-08 13:04 ` Baolu Lu
2023-03-08 15:06 ` Jason Gunthorpe
2023-03-09 2:03 ` Baolu Lu
2023-03-09 2:05 ` Baolu Lu
2023-03-08 0:35 ` [PATCH v2 10/17] iommufd: Reorganize iommufd_device_attach into iommufd_device_change_pt Jason Gunthorpe
2023-03-08 13:46 ` Baolu Lu
2023-03-10 11:26 ` Tian, Kevin
2023-03-10 15:01 ` Jason Gunthorpe
2023-03-08 0:35 ` [PATCH v2 11/17] iommu: Introduce a new iommu_group_replace_domain() API Jason Gunthorpe
2023-03-08 13:48 ` Baolu Lu
2023-03-08 0:35 ` [PATCH v2 12/17] iommufd: Add iommufd_device_replace() Jason Gunthorpe
2023-03-09 1:14 ` Baolu Lu
2023-03-10 11:48 ` Tian, Kevin
2023-03-10 15:04 ` Jason Gunthorpe
2023-03-08 0:35 ` [PATCH v2 13/17] iommufd: Make destroy_rwsem use a lock class per object type Jason Gunthorpe
2023-03-08 0:35 ` Jason Gunthorpe [this message]
2023-03-08 0:35 ` [PATCH v2 15/17] iommufd: Add IOMMU_HWPT_ALLOC Jason Gunthorpe
2023-03-09 1:21 ` Baolu Lu
2023-03-08 0:35 ` [PATCH v2 16/17] iommufd/selftest: Return the real idev id from selftest mock_domain Jason Gunthorpe
2023-03-08 0:35 ` [PATCH v2 17/17] iommufd/selftest: Add a selftest for IOMMU_HWPT_ALLOC Jason Gunthorpe
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=14-v2-51b9896e7862+8a8c-iommufd_alloc_jgg@nvidia.com \
--to=jgg@nvidia.com \
--cc=iommu@lists.linux.dev \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=yi.l.liu@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