All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add an iommufd selftest for replacement between domain and handle
@ 2025-02-26  5:01 Yi Liu
  2025-02-26  5:01 ` [PATCH 1/2] iommufd/selftest: Add a helper to get test device Yi Liu
  2025-02-26  5:01 ` [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle Yi Liu
  0 siblings, 2 replies; 8+ messages in thread
From: Yi Liu @ 2025-02-26  5:01 UTC (permalink / raw)
  To: kevin.tian, jgg; +Cc: joro, baolu.lu, yi.l.liu, iommu, nicolinc

Now iommu core has two sets of group attach APIs for RID. One is with
handle and another one without handle. iommu core allows replacing a
group which has been attached via the API without handle. However, no
known code used it yet. Add an iommufd selftest to cover it.

Based on the below series:
https://lore.kernel.org/linux-iommu/20250226011849.5102-1-yi.l.liu@intel.com/

Yi Liu (2):
  iommufd/selftest: Add a helper to get test device
  iommufd/selftest: Add coverage for RID replace between handle and
    non-handle

 drivers/iommu/iommufd/iommufd_test.h          |   5 +
 drivers/iommu/iommufd/selftest.c              | 134 ++++++++++++++++--
 tools/testing/selftests/iommu/iommufd.c       |   2 +
 .../selftests/iommu/iommufd_fail_nth.c        |   3 +
 tools/testing/selftests/iommu/iommufd_utils.h |  18 +++
 5 files changed, 151 insertions(+), 11 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] iommufd/selftest: Add a helper to get test device
  2025-02-26  5:01 [PATCH 0/2] Add an iommufd selftest for replacement between domain and handle Yi Liu
@ 2025-02-26  5:01 ` Yi Liu
  2025-02-26 21:45   ` Nicolin Chen
  2025-02-26  5:01 ` [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle Yi Liu
  1 sibling, 1 reply; 8+ messages in thread
From: Yi Liu @ 2025-02-26  5:01 UTC (permalink / raw)
  To: kevin.tian, jgg; +Cc: joro, baolu.lu, yi.l.liu, iommu, nicolinc

There is need to get the selftest device (sobj->type == TYPE_IDEV) in
multiple places, so have a helper to for it.

Signed-off-by: Yi Liu <yi.l.liu@intel.com>
---
 drivers/iommu/iommufd/selftest.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index f7d67bc15359..20a48cb067e6 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -968,29 +968,39 @@ 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)
+static struct selftest_obj *
+iommufd_test_get_self_test_device(struct iommufd_ctx *ictx, u32 id)
 {
 	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);
+	dev_obj = iommufd_get_object(ictx, id, IOMMUFD_OBJ_SELFTEST);
 	if (IS_ERR(dev_obj))
-		return PTR_ERR(dev_obj);
+		return ERR_CAST(dev_obj);
 
 	sobj = to_selftest_obj(dev_obj);
 	if (sobj->type != TYPE_IDEV) {
-		rc = -EINVAL;
-		goto out_dev_obj;
+		iommufd_put_object(ictx, dev_obj);
+		return ERR_PTR(-EINVAL);
 	}
+	return sobj;
+}
+
+/* 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 selftest_obj *sobj;
+	int rc;
+
+	sobj = iommufd_test_get_self_test_device(ucmd->ictx, device_id);
+	if (IS_ERR(sobj))
+		return PTR_ERR(sobj);
 
 	rc = iommufd_device_replace(sobj->idev.idev, &pt_id);
 	if (rc)
@@ -1000,7 +1010,7 @@ static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd,
 	rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
 
 out_dev_obj:
-	iommufd_put_object(ucmd->ictx, dev_obj);
+	iommufd_put_object(ucmd->ictx, &sobj->obj);
 	return rc;
 }
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle
  2025-02-26  5:01 [PATCH 0/2] Add an iommufd selftest for replacement between domain and handle Yi Liu
  2025-02-26  5:01 ` [PATCH 1/2] iommufd/selftest: Add a helper to get test device Yi Liu
@ 2025-02-26  5:01 ` Yi Liu
  2025-02-26 21:58   ` Nicolin Chen
  2025-02-27 20:11   ` Jason Gunthorpe
  1 sibling, 2 replies; 8+ messages in thread
From: Yi Liu @ 2025-02-26  5:01 UTC (permalink / raw)
  To: kevin.tian, jgg; +Cc: joro, baolu.lu, yi.l.liu, iommu, nicolinc

The iommu core supports replace between the attach with/without handle,
add test to cover it.

Signed-off-by: Yi Liu <yi.l.liu@intel.com>
---
 drivers/iommu/iommufd/iommufd_test.h          |   5 +
 drivers/iommu/iommufd/selftest.c              | 102 ++++++++++++++++++
 tools/testing/selftests/iommu/iommufd.c       |   2 +
 .../selftests/iommu/iommufd_fail_nth.c        |   3 +
 tools/testing/selftests/iommu/iommufd_utils.h |  18 ++++
 5 files changed, 130 insertions(+)

diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h
index a6b7a163f636..87dd123d1ff0 100644
--- a/drivers/iommu/iommufd/iommufd_test.h
+++ b/drivers/iommu/iommufd/iommufd_test.h
@@ -24,6 +24,7 @@ enum {
 	IOMMU_TEST_OP_MD_CHECK_IOTLB,
 	IOMMU_TEST_OP_TRIGGER_IOPF,
 	IOMMU_TEST_OP_DEV_CHECK_CACHE,
+	IOMMU_TEST_OP_MIX_REPLACE_HANDLE,
 };
 
 enum {
@@ -145,6 +146,10 @@ struct iommu_test_cmd {
 			__u32 id;
 			__u32 cache;
 		} check_dev_cache;
+		struct {
+			__u32 pt_id;
+			/* @id is stdev_id */
+		} mix_replace_handle;
 	};
 	__u32 last;
 };
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index 20a48cb067e6..f237a6ef58b7 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -1629,6 +1629,105 @@ static int iommufd_test_trigger_iopf(struct iommufd_ucmd *ucmd,
 	return 0;
 }
 
+static inline struct iommufd_hw_pagetable *
+iommufd_get_hwpt(struct iommufd_ucmd *ucmd, u32 id)
+{
+	struct iommufd_object *pt_obj;
+
+	pt_obj = iommufd_get_object(ucmd->ictx, id, IOMMUFD_OBJ_ANY);
+	if (IS_ERR(pt_obj))
+		return ERR_CAST(pt_obj);
+
+	if (pt_obj->type != IOMMUFD_OBJ_HWPT_NESTED &&
+	    pt_obj->type != IOMMUFD_OBJ_HWPT_PAGING) {
+		iommufd_put_object(ucmd->ictx, pt_obj);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return container_of(pt_obj, struct iommufd_hw_pagetable, obj);
+}
+
+static int iommufd_test_mixed_group_replace(struct iommufd_device *idev,
+					    struct iommu_domain *domain)
+{
+	struct iommu_domain *old_domain = iommu_get_domain_for_dev(idev->dev);
+	struct iommu_group *group = idev->igroup->group;
+	struct iommu_attach_handle *handle, *old_handle;
+	int ret;
+
+	/*
+	 * The test device should have been attached by the _handle API,
+	 * hence there should be an entry in the group->pasid_array.
+	 */
+	old_handle = iommu_attach_handle_get(group, IOMMU_NO_PASID, 0);
+	if (IS_ERR(old_handle))
+		return PTR_ERR(old_handle);
+
+	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
+	if (!handle)
+		return -ENOMEM;
+
+	mutex_lock(&idev->igroup->lock);
+	iommu_detach_group(domain, group);
+
+	/* attach without handle */
+	ret = iommu_attach_group(domain, group);
+	if (ret)
+		goto out_revert;
+
+	/* replace with handle should succeed */
+	ret = iommu_replace_group_handle(group, domain, handle);
+	if (ret)
+		goto out_revert;
+
+	if (iommu_get_domain_for_dev(idev->dev) != domain) {
+		ret = -ENODEV;
+		goto out_revert;
+	}
+
+	/* replace with the same handle/domain should succeed */
+	ret = iommu_replace_group_handle(group, domain, handle);
+
+out_revert:
+	WARN_ON(iommu_replace_group_handle(group, old_domain, old_handle));
+	mutex_unlock(&idev->igroup->lock);
+	kfree(handle);
+	return ret;
+}
+
+static int iommufd_test_mixed_handle_replace(struct iommufd_ucmd *ucmd,
+					     unsigned int device_id,
+					     u32 pt_id)
+{
+	struct iommufd_hw_pagetable *hwpt;
+	struct iommufd_device *idev;
+	struct iommu_domain *domain;
+	struct selftest_obj *sobj;
+	int rc;
+
+	sobj = iommufd_test_get_self_test_device(ucmd->ictx, device_id);
+	if (IS_ERR(sobj))
+		return PTR_ERR(sobj);
+
+	idev = sobj->idev.idev;
+
+	hwpt = iommufd_get_hwpt(ucmd, pt_id);
+	if (IS_ERR(hwpt)) {
+		rc = PTR_ERR(hwpt);
+		goto out_dev_obj;
+	}
+
+	domain = hwpt->domain;
+
+	rc = iommufd_test_mixed_group_replace(idev, domain);
+
+	iommufd_put_object(ucmd->ictx, &hwpt->obj);
+
+out_dev_obj:
+	iommufd_put_object(ucmd->ictx, &sobj->obj);
+	return rc;
+}
+
 void iommufd_selftest_destroy(struct iommufd_object *obj)
 {
 	struct selftest_obj *sobj = to_selftest_obj(obj);
@@ -1710,6 +1809,9 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
 					  cmd->dirty.flags);
 	case IOMMU_TEST_OP_TRIGGER_IOPF:
 		return iommufd_test_trigger_iopf(ucmd, cmd);
+	case IOMMU_TEST_OP_MIX_REPLACE_HANDLE:
+		return iommufd_test_mixed_handle_replace(ucmd, cmd->id,
+						cmd->mix_replace_handle.pt_id);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
index a1b2b657999d..8d8ce97b53ee 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -1951,6 +1951,8 @@ TEST_F(iommufd_mock_domain, alloc_hwpt)
 		test_cmd_hwpt_alloc(self->idev_ids[i], self->ioas_id,
 				    IOMMU_HWPT_ALLOC_NEST_PARENT, &hwpt_id[1]);
 
+		test_cmd_mixed_replace(self->stdev_ids[i], hwpt_id[0]);
+
 		/* Do a hw_pagetable rotation test */
 		test_cmd_mock_domain_replace(self->stdev_ids[i], hwpt_id[0]);
 		EXPECT_ERRNO(EBUSY, _test_ioctl_destroy(self->fd, hwpt_id[0]));
diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
index 64b1f8e1b0cf..fa6d8cbbe6e1 100644
--- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
+++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
@@ -665,6 +665,9 @@ TEST_FAIL_NTH(basic_fail_nth, device)
 				 IOMMU_HWPT_DATA_NONE, 0, 0))
 		return -1;
 
+	if (_test_cmd_mixed_replace(self->fd, stdev_id, hwpt_id))
+		return -1;
+
 	if (_test_cmd_mock_domain_replace(self->fd, stdev_id, ioas_id2, NULL))
 		return -1;
 
diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
index d979f5b0efe8..27d51f880369 100644
--- a/tools/testing/selftests/iommu/iommufd_utils.h
+++ b/tools/testing/selftests/iommu/iommufd_utils.h
@@ -936,3 +936,21 @@ static int _test_cmd_vdevice_alloc(int fd, __u32 viommu_id, __u32 idev_id,
 	EXPECT_ERRNO(_errno,                                                 \
 		     _test_cmd_vdevice_alloc(self->fd, viommu_id, idev_id,   \
 					     virt_id, vdev_id))
+
+static int _test_cmd_mixed_replace(int fd, __u32 stdev_id, __u32 pt_id)
+{
+	struct iommu_test_cmd test_mixed_replace = {
+		.size = sizeof(test_mixed_replace),
+		.op = IOMMU_TEST_OP_MIX_REPLACE_HANDLE,
+		.id = stdev_id,
+		.mix_replace_handle = {
+			.pt_id = pt_id,
+		},
+	};
+
+	return ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_MIX_REPLACE_HANDLE),
+		     &test_mixed_replace);
+}
+
+#define test_cmd_mixed_replace(stdev_id, hwpt_id)                         \
+	ASSERT_EQ(0, _test_cmd_mixed_replace(self->fd, stdev_id, hwpt_id))
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] iommufd/selftest: Add a helper to get test device
  2025-02-26  5:01 ` [PATCH 1/2] iommufd/selftest: Add a helper to get test device Yi Liu
@ 2025-02-26 21:45   ` Nicolin Chen
  2025-02-27  0:41     ` Yi Liu
  0 siblings, 1 reply; 8+ messages in thread
From: Nicolin Chen @ 2025-02-26 21:45 UTC (permalink / raw)
  To: Yi Liu; +Cc: kevin.tian, jgg, joro, baolu.lu, iommu

On Tue, Feb 25, 2025 at 09:01:29PM -0800, Yi Liu wrote:
> There is need to get the selftest device (sobj->type == TYPE_IDEV) in
> multiple places, so have a helper to for it.
> 
> Signed-off-by: Yi Liu <yi.l.liu@intel.com>

Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>

With two nits below:

> @@ -968,29 +968,39 @@ 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)
> +static struct selftest_obj *
> +iommufd_test_get_self_test_device(struct iommufd_ctx *ictx, u32 id)

Since it wants selftest_obj, maybe just iommufd_test_get_selftest_obj.

> @@ -1000,7 +1010,7 @@ static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd,
>  	rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
>  
>  out_dev_obj:

out_sobj:

> -	iommufd_put_object(ucmd->ictx, dev_obj);
> +	iommufd_put_object(ucmd->ictx, &sobj->obj);
>  	return rc;

Thanks
Nic

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle
  2025-02-26  5:01 ` [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle Yi Liu
@ 2025-02-26 21:58   ` Nicolin Chen
  2025-02-27  1:24     ` Yi Liu
  2025-02-27 20:11   ` Jason Gunthorpe
  1 sibling, 1 reply; 8+ messages in thread
From: Nicolin Chen @ 2025-02-26 21:58 UTC (permalink / raw)
  To: Yi Liu; +Cc: kevin.tian, jgg, joro, baolu.lu, iommu

On Tue, Feb 25, 2025 at 09:01:30PM -0800, Yi Liu wrote:
> The iommu core supports replace between the attach with/without handle,
> add test to cover it.
> 
> Signed-off-by: Yi Liu <yi.l.liu@intel.com>
[...]
> +static inline struct iommufd_hw_pagetable *
> +iommufd_get_hwpt(struct iommufd_ucmd *ucmd, u32 id)
> +{
> +	struct iommufd_object *pt_obj;
> +
> +	pt_obj = iommufd_get_object(ucmd->ictx, id, IOMMUFD_OBJ_ANY);
> +	if (IS_ERR(pt_obj))
> +		return ERR_CAST(pt_obj);
> +
> +	if (pt_obj->type != IOMMUFD_OBJ_HWPT_NESTED &&
> +	    pt_obj->type != IOMMUFD_OBJ_HWPT_PAGING) {
> +		iommufd_put_object(ucmd->ictx, pt_obj);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	return container_of(pt_obj, struct iommufd_hw_pagetable, obj);

Will there be any other caller potentially?

> +static int iommufd_test_mixed_group_replace(struct iommufd_device *idev,
> +					    struct iommu_domain *domain)
> +{
> +	struct iommu_domain *old_domain = iommu_get_domain_for_dev(idev->dev);
> +	struct iommu_group *group = idev->igroup->group;
> +	struct iommu_attach_handle *handle, *old_handle;
> +	int ret;
> +
> +	/*
> +	 * The test device should have been attached by the _handle API,
> +	 * hence there should be an entry in the group->pasid_array.
> +	 */
> +	old_handle = iommu_attach_handle_get(group, IOMMU_NO_PASID, 0);
> +	if (IS_ERR(old_handle))
> +		return PTR_ERR(old_handle);
> +
> +	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
> +	if (!handle)
> +		return -ENOMEM;
> +
> +	mutex_lock(&idev->igroup->lock);
> +	iommu_detach_group(domain, group);
> +
> +	/* attach without handle */
> +	ret = iommu_attach_group(domain, group);
> +	if (ret)
> +		goto out_revert;
> +
> +	/* replace with handle should succeed */
> +	ret = iommu_replace_group_handle(group, domain, handle);
> +	if (ret)
> +		goto out_revert;
> +
> +	if (iommu_get_domain_for_dev(idev->dev) != domain) {
> +		ret = -ENODEV;
> +		goto out_revert;
> +	}
> +
> +	/* replace with the same handle/domain should succeed */
> +	ret = iommu_replace_group_handle(group, domain, handle);

Hmm, this is switching between domains with/without a handle?
It feels odd to me, as we should do this in the user space code
other than in the kernel?

Also, I think that any iommufd-allocated domain (via hwpt) has
an attach_handle now, right? Mind elaborating a use case with
iommufd that can switch between domains with/without a handle?

Thanks
Nic

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] iommufd/selftest: Add a helper to get test device
  2025-02-26 21:45   ` Nicolin Chen
@ 2025-02-27  0:41     ` Yi Liu
  0 siblings, 0 replies; 8+ messages in thread
From: Yi Liu @ 2025-02-27  0:41 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: kevin.tian, jgg, joro, baolu.lu, iommu

On 2025/2/27 05:45, Nicolin Chen wrote:
> On Tue, Feb 25, 2025 at 09:01:29PM -0800, Yi Liu wrote:
>> There is need to get the selftest device (sobj->type == TYPE_IDEV) in
>> multiple places, so have a helper to for it.
>>
>> Signed-off-by: Yi Liu <yi.l.liu@intel.com>
> 
> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
> 
> With two nits below:
> 
>> @@ -968,29 +968,39 @@ 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)
>> +static struct selftest_obj *
>> +iommufd_test_get_self_test_device(struct iommufd_ctx *ictx, u32 id)
> 
> Since it wants selftest_obj, maybe just iommufd_test_get_selftest_obj.
> 
>> @@ -1000,7 +1010,7 @@ static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd,
>>   	rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
>>   
>>   out_dev_obj:
> 
> out_sobj:
> 
>> -	iommufd_put_object(ucmd->ictx, dev_obj);
>> +	iommufd_put_object(ucmd->ictx, &sobj->obj);
>>   	return rc;
got it.

-- 
Regards,
Yi Liu

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle
  2025-02-26 21:58   ` Nicolin Chen
@ 2025-02-27  1:24     ` Yi Liu
  0 siblings, 0 replies; 8+ messages in thread
From: Yi Liu @ 2025-02-27  1:24 UTC (permalink / raw)
  To: Nicolin Chen; +Cc: kevin.tian, jgg, joro, baolu.lu, iommu

On 2025/2/27 05:58, Nicolin Chen wrote:
> On Tue, Feb 25, 2025 at 09:01:30PM -0800, Yi Liu wrote:
>> The iommu core supports replace between the attach with/without handle,
>> add test to cover it.
>>
>> Signed-off-by: Yi Liu <yi.l.liu@intel.com>
> [...]
>> +static inline struct iommufd_hw_pagetable *
>> +iommufd_get_hwpt(struct iommufd_ucmd *ucmd, u32 id)
>> +{
>> +	struct iommufd_object *pt_obj;
>> +
>> +	pt_obj = iommufd_get_object(ucmd->ictx, id, IOMMUFD_OBJ_ANY);
>> +	if (IS_ERR(pt_obj))
>> +		return ERR_CAST(pt_obj);
>> +
>> +	if (pt_obj->type != IOMMUFD_OBJ_HWPT_NESTED &&
>> +	    pt_obj->type != IOMMUFD_OBJ_HWPT_PAGING) {
>> +		iommufd_put_object(ucmd->ictx, pt_obj);
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	return container_of(pt_obj, struct iommufd_hw_pagetable, obj);
> 
> Will there be any other caller potentially?

yes. The iommufd pasid series has another selftest op that needs it.

https://lore.kernel.org/linux-iommu/20250226114032.4591-1-yi.l.liu@intel.com/T/#mdea85bdfec37d86fe7275b0944df5d39e1858422

>> +static int iommufd_test_mixed_group_replace(struct iommufd_device *idev,
>> +					    struct iommu_domain *domain)
>> +{
>> +	struct iommu_domain *old_domain = iommu_get_domain_for_dev(idev->dev);
>> +	struct iommu_group *group = idev->igroup->group;
>> +	struct iommu_attach_handle *handle, *old_handle;
>> +	int ret;
>> +
>> +	/*
>> +	 * The test device should have been attached by the _handle API,
>> +	 * hence there should be an entry in the group->pasid_array.
>> +	 */
>> +	old_handle = iommu_attach_handle_get(group, IOMMU_NO_PASID, 0);
>> +	if (IS_ERR(old_handle))
>> +		return PTR_ERR(old_handle);
>> +
>> +	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
>> +	if (!handle)
>> +		return -ENOMEM;
>> +
>> +	mutex_lock(&idev->igroup->lock);
>> +	iommu_detach_group(domain, group);
>> +
>> +	/* attach without handle */
>> +	ret = iommu_attach_group(domain, group);
>> +	if (ret)
>> +		goto out_revert;
>> +
>> +	/* replace with handle should succeed */
>> +	ret = iommu_replace_group_handle(group, domain, handle);
>> +	if (ret)
>> +		goto out_revert;
>> +
>> +	if (iommu_get_domain_for_dev(idev->dev) != domain) {
>> +		ret = -ENODEV;
>> +		goto out_revert;
>> +	}
>> +
>> +	/* replace with the same handle/domain should succeed */
>> +	ret = iommu_replace_group_handle(group, domain, handle);
> 
> Hmm, this is switching between domains with/without a handle?
> It feels odd to me, as we should do this in the user space code
> other than in the kernel?

yes. but iommufd now always attach with handle.

> Also, I think that any iommufd-allocated domain (via hwpt) has
> an attach_handle now, right? Mind elaborating a use case with
> iommufd that can switch between domains with/without a handle?

I don't have a usage yet. It's a remark[1] from Jason that reminds me
that we now actually support it but does not have any code to test
it. Hence, I got this test case.

[1] https://lore.kernel.org/linux-iommu/20250218195756.GG4183890@nvidia.com/

-- 
Regards,
Yi Liu

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle
  2025-02-26  5:01 ` [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle Yi Liu
  2025-02-26 21:58   ` Nicolin Chen
@ 2025-02-27 20:11   ` Jason Gunthorpe
  1 sibling, 0 replies; 8+ messages in thread
From: Jason Gunthorpe @ 2025-02-27 20:11 UTC (permalink / raw)
  To: Yi Liu; +Cc: kevin.tian, joro, baolu.lu, iommu, nicolinc

On Tue, Feb 25, 2025 at 09:01:30PM -0800, Yi Liu wrote:
> The iommu core supports replace between the attach with/without handle,
> add test to cover it.

Hum, it is not really an iommufd test anymore like this..

Though I see why you'd want to it this way

Jason

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-02-27 20:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-26  5:01 [PATCH 0/2] Add an iommufd selftest for replacement between domain and handle Yi Liu
2025-02-26  5:01 ` [PATCH 1/2] iommufd/selftest: Add a helper to get test device Yi Liu
2025-02-26 21:45   ` Nicolin Chen
2025-02-27  0:41     ` Yi Liu
2025-02-26  5:01 ` [PATCH 2/2] iommufd/selftest: Add coverage for RID replace between handle and non-handle Yi Liu
2025-02-26 21:58   ` Nicolin Chen
2025-02-27  1:24     ` Yi Liu
2025-02-27 20:11   ` Jason Gunthorpe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.