This allows verifying the ids xarray of struct mock_viommu, and confirming the correctness of an IOMMU_VIOMMU_SET_DEV_ID call. Signed-off-by: Nicolin Chen <nicolinc@xxxxxxxxxx> --- drivers/iommu/iommufd/iommufd_test.h | 5 +++ drivers/iommu/iommufd/selftest.c | 32 +++++++++++++++++++ tools/testing/selftests/iommu/iommufd.c | 7 ++++ tools/testing/selftests/iommu/iommufd_utils.h | 24 ++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/drivers/iommu/iommufd/iommufd_test.h b/drivers/iommu/iommufd/iommufd_test.h index e854d3f67205..91af979a0c23 100644 --- a/drivers/iommu/iommufd/iommufd_test.h +++ b/drivers/iommu/iommufd/iommufd_test.h @@ -22,6 +22,7 @@ enum { IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS, IOMMU_TEST_OP_DIRTY, IOMMU_TEST_OP_MD_CHECK_IOTLB, + IOMMU_TEST_OP_MV_CHECK_DEVID, }; enum { @@ -127,6 +128,10 @@ struct iommu_test_cmd { __u32 id; __u32 iotlb; } check_iotlb; + struct { + __u32 idev_id; + __u32 dev_id; + } check_dev_id; }; __u32 last; }; diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index 4caed9304065..b7d0ce3d3659 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -999,6 +999,34 @@ static int iommufd_test_md_check_iotlb(struct iommufd_ucmd *ucmd, return rc; } +static int iommufd_test_mv_check_dev_id(struct iommufd_ucmd *ucmd, + u32 viommu_id, unsigned int idev_id, + u32 dev_id) +{ + struct iommufd_device *idev; + struct mock_viommu *mv; + int rc = 0; + + mv = container_of(iommufd_get_viommu(ucmd, viommu_id), + struct mock_viommu, core); + if (IS_ERR(mv)) + return PTR_ERR(mv); + + idev = iommufd_get_device(ucmd, idev_id); + if (IS_ERR(idev)) { + rc = PTR_ERR(idev); + goto out_put_viommu; + } + + if (idev->dev != xa_load(&mv->ids, dev_id)) + rc = -EINVAL; + + iommufd_put_object(ucmd->ictx, &idev->obj); +out_put_viommu: + iommufd_put_object(ucmd->ictx, &mv->core.obj); + return rc; +} + struct selftest_access { struct iommufd_access *access; struct file *file; @@ -1484,6 +1512,10 @@ int iommufd_test(struct iommufd_ucmd *ucmd) return iommufd_test_md_check_iotlb(ucmd, cmd->id, cmd->check_iotlb.id, cmd->check_iotlb.iotlb); + case IOMMU_TEST_OP_MV_CHECK_DEVID: + return iommufd_test_mv_check_dev_id(ucmd, cmd->id, + cmd->check_dev_id.idev_id, + cmd->check_dev_id.dev_id); case IOMMU_TEST_OP_CREATE_ACCESS: return iommufd_test_create_access(ucmd, cmd->id, cmd->create_access.flags); diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c index 378fbf00730e..3af5932c227c 100644 --- a/tools/testing/selftests/iommu/iommufd.c +++ b/tools/testing/selftests/iommu/iommufd.c @@ -288,14 +288,21 @@ TEST_F(iommufd_ioas, viommu) test_err_viommu_set_dev_id(EINVAL, dev_id, viommu_id, 1ULL << 32); test_cmd_viommu_set_dev_id(dev_id, viommu_id, 0x99); test_err_viommu_set_dev_id(EBUSY, dev_id, viommu_id, 0x99); + test_cmd_viommu_check_dev_id(viommu_id, dev_id, 0x99); test_cmd_mock_domain(self->ioas_id, &stdev2, &hwpt2, &device2); test_err_viommu_set_dev_id(EBUSY, device2, viommu_id, 0x99); test_cmd_viommu_set_dev_id(device2, viommu_id, 0xaa); test_err_viommu_set_dev_id(EBUSY, device2, viommu_id, 0xaa); + test_cmd_viommu_check_dev_id(viommu_id, dev_id, 0x99); + test_cmd_viommu_check_dev_id(viommu_id, device2, 0xaa); + test_ioctl_destroy(stdev2); + test_cmd_viommu_check_dev_id(viommu_id, dev_id, 0x99); + test_err_viommu_check_dev_id(ENOENT, viommu_id, device2, 0xaa); test_ioctl_destroy(viommu_id); + test_err_viommu_check_dev_id(ENOENT, viommu_id, dev_id, 0x99); test_ioctl_destroy(hwpt_id); } else { test_err_viommu_alloc(ENOENT, dev_id, hwpt_id, &viommu_id); diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h index 81e9184fd1d5..e926fa289baa 100644 --- a/tools/testing/selftests/iommu/iommufd_utils.h +++ b/tools/testing/selftests/iommu/iommufd_utils.h @@ -731,3 +731,27 @@ static int _test_cmd_viommu_set_dev_id(int fd, __u32 device_id, EXPECT_ERRNO(_errno, \ _test_cmd_viommu_set_dev_id(self->fd, device_id, \ viommu_id, virtual_id)) + +static int _test_cmd_viommu_check_dev_id(int fd, __u32 viommu_id, + __u32 device_id, __u64 virtual_id) +{ + struct iommu_test_cmd test_cmd = { + .size = sizeof(test_cmd), + .op = IOMMU_TEST_OP_MV_CHECK_DEVID, + .id = viommu_id, + .check_dev_id = { + .idev_id = device_id, + .dev_id = virtual_id, + }, + }; + return ioctl(fd, _IOMMU_TEST_CMD(IOMMU_TEST_OP_MV_CHECK_DEVID), + &test_cmd); +} +#define test_cmd_viommu_check_dev_id(viommu_id, device_id, expected) \ + ASSERT_EQ(0, _test_cmd_viommu_check_dev_id(self->fd, viommu_id, \ + device_id, expected)) + +#define test_err_viommu_check_dev_id(_errno, viommu_id, device_id, expected) \ + EXPECT_ERRNO(_errno, \ + _test_cmd_viommu_check_dev_id(self->fd, viommu_id, \ + device_id, expected)) -- 2.43.0