lkml.org 
[lkml]   [2023]   [Oct]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v7 10/10] iommufd/selftest: Add coverage for IOMMU_HWPT_ALLOC with nested HWPTs
    Date
    From: Nicolin Chen <nicolinc@nvidia.com>

    The IOMMU_HWPT_ALLOC ioctl now supports passing user_data to allocate a
    user-managed domain for nested HWPTs. Add its coverage for that. Also,
    update _test_cmd_hwpt_alloc() and add test_cmd/err_hwpt_alloc_nested().

    Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
    Signed-off-by: Yi Liu <yi.l.liu@intel.com>
    Reviewed-by: Kevin Tian <kevin.tian@intel.com>
    Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
    ---
    tools/testing/selftests/iommu/iommufd.c | 115 ++++++++++++++++++
    .../selftests/iommu/iommufd_fail_nth.c | 3 +-
    tools/testing/selftests/iommu/iommufd_utils.h | 30 +++--
    3 files changed, 140 insertions(+), 8 deletions(-)

    diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
    index 76a4351e3434..6ed328c863c4 100644
    --- a/tools/testing/selftests/iommu/iommufd.c
    +++ b/tools/testing/selftests/iommu/iommufd.c
    @@ -264,6 +264,121 @@ TEST_F(iommufd_ioas, ioas_destroy)
    }
    }

    +TEST_F(iommufd_ioas, alloc_hwpt_nested)
    +{
    + const uint32_t min_data_len =
    + offsetofend(struct iommu_hwpt_selftest, iotlb);
    + struct iommu_hwpt_selftest data = {
    + .iotlb = IOMMU_TEST_IOTLB_DEFAULT,
    + };
    + uint32_t nested_hwpt_id[2] = {};
    + uint32_t parent_hwpt_id = 0;
    + uint32_t parent_hwpt_id_not_work = 0;
    + uint32_t test_hwpt_id = 0;
    +
    + if (self->device_id) {
    + /* Negative tests */
    + test_err_hwpt_alloc(ENOENT, self->ioas_id, self->device_id, 0,
    + &test_hwpt_id);
    + test_err_hwpt_alloc(EINVAL, self->device_id, self->device_id, 0,
    + &test_hwpt_id);
    +
    + test_cmd_hwpt_alloc(self->device_id, self->ioas_id,
    + IOMMU_HWPT_ALLOC_NEST_PARENT,
    + &parent_hwpt_id);
    +
    + test_cmd_hwpt_alloc(self->device_id, self->ioas_id, 0,
    + &parent_hwpt_id_not_work);
    +
    + /* Negative nested tests */
    + test_err_hwpt_alloc_nested(EINVAL, self->device_id,
    + parent_hwpt_id, 0,
    + &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_NONE, &data,
    + sizeof(data));
    + test_err_hwpt_alloc_nested(EOPNOTSUPP, self->device_id,
    + parent_hwpt_id, 0,
    + &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_SELFTEST + 1, &data,
    + sizeof(data));
    + test_err_hwpt_alloc_nested(EINVAL, self->device_id,
    + parent_hwpt_id, 0,
    + &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_SELFTEST, &data,
    + min_data_len - 1);
    + test_err_hwpt_alloc_nested(EFAULT, self->device_id,
    + parent_hwpt_id, 0,
    + &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_SELFTEST, NULL,
    + sizeof(data));
    + test_err_hwpt_alloc_nested(
    + EOPNOTSUPP, self->device_id, parent_hwpt_id,
    + IOMMU_HWPT_ALLOC_NEST_PARENT, &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_SELFTEST, &data, sizeof(data));
    + test_err_hwpt_alloc_nested(EINVAL, self->device_id,
    + parent_hwpt_id_not_work, 0,
    + &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_SELFTEST, &data,
    + sizeof(data));
    +
    + /* Allocate two nested hwpts sharing one common parent hwpt */
    + test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0,
    + &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_SELFTEST, &data,
    + sizeof(data));
    + test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id, 0,
    + &nested_hwpt_id[1],
    + IOMMU_HWPT_DATA_SELFTEST, &data,
    + sizeof(data));
    +
    + /* Negative test: a nested hwpt on top of a nested hwpt */
    + test_err_hwpt_alloc_nested(EINVAL, self->device_id,
    + nested_hwpt_id[0], 0, &test_hwpt_id,
    + IOMMU_HWPT_DATA_SELFTEST, &data,
    + sizeof(data));
    + /* Negative test: parent hwpt now cannot be freed */
    + EXPECT_ERRNO(EBUSY,
    + _test_ioctl_destroy(self->fd, parent_hwpt_id));
    +
    + /* Attach device to nested_hwpt_id[0] that then will be busy */
    + test_cmd_mock_domain_replace(self->stdev_id, nested_hwpt_id[0]);
    + EXPECT_ERRNO(EBUSY,
    + _test_ioctl_destroy(self->fd, nested_hwpt_id[0]));
    +
    + /* Switch from nested_hwpt_id[0] to nested_hwpt_id[1] */
    + test_cmd_mock_domain_replace(self->stdev_id, nested_hwpt_id[1]);
    + EXPECT_ERRNO(EBUSY,
    + _test_ioctl_destroy(self->fd, nested_hwpt_id[1]));
    + test_ioctl_destroy(nested_hwpt_id[0]);
    +
    + /* Detach from nested_hwpt_id[1] and destroy it */
    + test_cmd_mock_domain_replace(self->stdev_id, parent_hwpt_id);
    + test_ioctl_destroy(nested_hwpt_id[1]);
    +
    + /* Detach from the parent hw_pagetable and destroy it */
    + test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
    + test_ioctl_destroy(parent_hwpt_id);
    + test_ioctl_destroy(parent_hwpt_id_not_work);
    + } else {
    + test_err_hwpt_alloc(ENOENT, self->device_id, self->ioas_id, 0,
    + &parent_hwpt_id);
    + test_err_hwpt_alloc_nested(ENOENT, self->device_id,
    + parent_hwpt_id, 0,
    + &nested_hwpt_id[0],
    + IOMMU_HWPT_DATA_SELFTEST, &data,
    + sizeof(data));
    + test_err_hwpt_alloc_nested(ENOENT, self->device_id,
    + parent_hwpt_id, 0,
    + &nested_hwpt_id[1],
    + IOMMU_HWPT_DATA_SELFTEST, &data,
    + sizeof(data));
    + test_err_mock_domain_replace(ENOENT, self->stdev_id,
    + nested_hwpt_id[0]);
    + test_err_mock_domain_replace(ENOENT, self->stdev_id,
    + nested_hwpt_id[1]);
    + }
    +}
    +
    TEST_F(iommufd_ioas, hwpt_attach)
    {
    /* Create a device attached directly to a hwpt */
    diff --git a/tools/testing/selftests/iommu/iommufd_fail_nth.c b/tools/testing/selftests/iommu/iommufd_fail_nth.c
    index ff735bdd833e..f590417cd67a 100644
    --- a/tools/testing/selftests/iommu/iommufd_fail_nth.c
    +++ b/tools/testing/selftests/iommu/iommufd_fail_nth.c
    @@ -615,7 +615,8 @@ TEST_FAIL_NTH(basic_fail_nth, device)
    if (_test_cmd_get_hw_info(self->fd, idev_id, &info, sizeof(info), NULL))
    return -1;

    - if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0, &hwpt_id))
    + if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0, &hwpt_id,
    + IOMMU_HWPT_DATA_NONE, 0, 0))
    return -1;

    if (_test_cmd_mock_domain_replace(self->fd, stdev_id, ioas_id2, NULL))
    diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
    index e263bf80a977..050e9751321c 100644
    --- a/tools/testing/selftests/iommu/iommufd_utils.h
    +++ b/tools/testing/selftests/iommu/iommufd_utils.h
    @@ -154,13 +154,17 @@ static int _test_cmd_mock_domain_replace(int fd, __u32 stdev_id, __u32 pt_id,
    pt_id, NULL))

    static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,
    - __u32 flags, __u32 *hwpt_id)
    + __u32 flags, __u32 *hwpt_id, __u32 data_type,
    + void *data, size_t data_len)
    {
    struct iommu_hwpt_alloc cmd = {
    .size = sizeof(cmd),
    .flags = flags,
    .dev_id = device_id,
    .pt_id = pt_id,
    + .data_type = data_type,
    + .data_len = data_len,
    + .data_uptr = (uint64_t)data,
    };
    int ret;

    @@ -172,12 +176,24 @@ static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,
    return 0;
    }

    -#define test_cmd_hwpt_alloc(device_id, pt_id, flags, hwpt_id) \
    - ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, \
    - pt_id, flags, hwpt_id))
    -#define test_err_hwpt_alloc(_errno, device_id, pt_id, flags, hwpt_id) \
    - EXPECT_ERRNO(_errno, _test_cmd_hwpt_alloc(self->fd, device_id, \
    - pt_id, flags, hwpt_id))
    +#define test_cmd_hwpt_alloc(device_id, pt_id, flags, hwpt_id) \
    + ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
    + hwpt_id, IOMMU_HWPT_DATA_NONE, NULL, \
    + 0))
    +#define test_err_hwpt_alloc(_errno, device_id, pt_id, flags, hwpt_id) \
    + EXPECT_ERRNO(_errno, _test_cmd_hwpt_alloc( \
    + self->fd, device_id, pt_id, flags, \
    + hwpt_id, IOMMU_HWPT_DATA_NONE, NULL, 0))
    +
    +#define test_cmd_hwpt_alloc_nested(device_id, pt_id, flags, hwpt_id, \
    + data_type, data, data_len) \
    + ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
    + hwpt_id, data_type, data, data_len))
    +#define test_err_hwpt_alloc_nested(_errno, device_id, pt_id, flags, hwpt_id, \
    + data_type, data, data_len) \
    + EXPECT_ERRNO(_errno, \
    + _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
    + hwpt_id, data_type, data, data_len))

    static int _test_cmd_access_replace_ioas(int fd, __u32 access_id,
    unsigned int ioas_id)
    --
    2.34.1
    \
     
     \ /
      Last update: 2023-10-26 06:41    [W:3.312 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site