When attaching a device to a vIOMMU-based nested domain, vdev_id must be
present. Add a piece of code hard-requesting it, preparing for a vEVENTQ
support in the following patch. Then, update the TEST_F.

A HWPT-based nested domain will return a NULL new_viommu, thus no such a
vDEVICE requirement.

Signed-off-by: Nicolin Chen <nicol...@nvidia.com>
---
 drivers/iommu/iommufd/selftest.c        | 23 +++++++++++++++++++++++
 tools/testing/selftests/iommu/iommufd.c |  5 +++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index a0de6d6d4e68..d1438d81e664 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -161,7 +161,10 @@ enum selftest_obj_type {
 
 struct mock_dev {
        struct device dev;
+       struct mock_viommu *viommu;
+       struct rw_semaphore viommu_rwsem;
        unsigned long flags;
+       unsigned long vdev_id;
        int id;
        u32 cache[MOCK_DEV_CACHE_NUM];
 };
@@ -193,10 +196,29 @@ static int mock_domain_nop_attach(struct iommu_domain 
*domain,
                                  struct device *dev)
 {
        struct mock_dev *mdev = to_mock_dev(dev);
+       struct mock_viommu *new_viommu = NULL;
+       unsigned long vdev_id = 0;
 
        if (domain->dirty_ops && (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
                return -EINVAL;
 
+       iommu_group_mutex_assert(dev);
+       if (domain->type == IOMMU_DOMAIN_NESTED) {
+               new_viommu = to_mock_nested(domain)->mock_viommu;
+               if (new_viommu) {
+                       vdev_id = iommufd_viommu_get_vdev_id(&new_viommu->core,
+                                                            dev);
+                       if (!vdev_id)
+                               return -ENOENT;
+               }
+       }
+       if (new_viommu != mdev->viommu) {
+               down_write(&mdev->viommu_rwsem);
+               mdev->viommu = new_viommu;
+               mdev->vdev_id = vdev_id;
+               up_write(&mdev->viommu_rwsem);
+       }
+
        return 0;
 }
 
@@ -861,6 +883,7 @@ static struct mock_dev *mock_dev_create(unsigned long 
dev_flags)
        if (!mdev)
                return ERR_PTR(-ENOMEM);
 
+       init_rwsem(&mdev->viommu_rwsem);
        device_initialize(&mdev->dev);
        mdev->flags = dev_flags;
        mdev->dev.release = mock_dev_release;
diff --git a/tools/testing/selftests/iommu/iommufd.c 
b/tools/testing/selftests/iommu/iommufd.c
index a1b2b657999d..212e5d62e13d 100644
--- a/tools/testing/selftests/iommu/iommufd.c
+++ b/tools/testing/selftests/iommu/iommufd.c
@@ -2736,6 +2736,7 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
        uint32_t iopf_hwpt_id;
        uint32_t fault_id;
        uint32_t fault_fd;
+       uint32_t vdev_id;
 
        if (self->device_id) {
                test_ioctl_fault_alloc(&fault_id, &fault_fd);
@@ -2752,6 +2753,10 @@ TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
                        &iopf_hwpt_id, IOMMU_HWPT_DATA_SELFTEST, &data,
                        sizeof(data));
 
+               /* Must allocate vdevice before attaching to a nested hwpt */
+               test_err_mock_domain_replace(ENOENT, self->stdev_id,
+                                            iopf_hwpt_id);
+               test_cmd_vdevice_alloc(viommu_id, dev_id, 0x99, &vdev_id);
                test_cmd_mock_domain_replace(self->stdev_id, iopf_hwpt_id);
                EXPECT_ERRNO(EBUSY,
                             _test_ioctl_destroy(self->fd, iopf_hwpt_id));
-- 
2.43.0


Reply via email to