lkml.org 
[lkml]   [2023]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 09/11] iommufd/selftest: Add coverage for IOMMU_HWPT_ALLOC with user data
    Date
    From: Nicolin Chen <nicolinc@nvidia.com>

    The IOMMU_HWPT_ALLOC ioctl now supports passing user_data to allocate a
    customized domain. Add its coverage for both a regular domain case and
    a nested domain case.

    Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
    Signed-off-by: Yi Liu <yi.l.liu@intel.com>
    ---
    tools/testing/selftests/iommu/iommufd.c | 114 +++++++++++++++++-
    tools/testing/selftests/iommu/iommufd_utils.h | 36 ++++++
    2 files changed, 149 insertions(+), 1 deletion(-)

    diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c
    index fa2324741ad2..568f80f596ad 100644
    --- a/tools/testing/selftests/iommu/iommufd.c
    +++ b/tools/testing/selftests/iommu/iommufd.c
    @@ -122,6 +122,7 @@ TEST_F(iommufd, cmd_length)
    TEST_LENGTH(iommu_option, IOMMU_OPTION);
    TEST_LENGTH(iommu_vfio_ioas, IOMMU_VFIO_IOAS);
    TEST_LENGTH(iommu_hw_info, IOMMU_DEVICE_GET_HW_INFO);
    + TEST_LENGTH(iommu_hwpt_alloc, IOMMU_HWPT_ALLOC);
    #undef TEST_LENGTH
    }

    @@ -194,6 +195,7 @@ FIXTURE_VARIANT(iommufd_ioas)
    {
    unsigned int mock_domains;
    unsigned int memory_limit;
    + bool new_hwpt;
    };

    FIXTURE_SETUP(iommufd_ioas)
    @@ -233,6 +235,12 @@ FIXTURE_VARIANT_ADD(iommufd_ioas, mock_domain)
    .mock_domains = 1,
    };

    +FIXTURE_VARIANT_ADD(iommufd_ioas, mock_domain_hwpt)
    +{
    + .mock_domains = 1,
    + .new_hwpt = true,
    +};
    +
    FIXTURE_VARIANT_ADD(iommufd_ioas, two_mock_domain)
    {
    .mock_domains = 2,
    @@ -260,6 +268,93 @@ TEST_F(iommufd_ioas, ioas_destroy)
    }
    }

    +TEST_F(iommufd_ioas, hwpt_alloc)
    +{
    + uint32_t new_hwpt_id = 0;
    +
    + if (self->stdev_id && self->device_id) {
    + test_cmd_hwpt_alloc(self->device_id, self->ioas_id, &new_hwpt_id);
    + test_cmd_mock_domain_replace(self->stdev_id, new_hwpt_id);
    + /* hw_pagetable cannot be freed if a device is attached to it */
    + EXPECT_ERRNO(EBUSY, _test_ioctl_destroy(self->fd, new_hwpt_id));
    +
    + /* Detach from the new hw_pagetable and try again */
    + test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
    + test_ioctl_destroy(new_hwpt_id);
    + } else {
    + test_err_cmd_hwpt_alloc(ENOENT, self->device_id,
    + self->ioas_id, &new_hwpt_id);
    + test_err_mock_domain_replace(ENOENT,
    + self->stdev_id, new_hwpt_id);
    + }
    +}
    +
    +TEST_F(iommufd_ioas, nested_hwpt_alloc)
    +{
    + uint32_t nested_hwpt_id[2] = {};
    + uint32_t parent_hwpt_id = 0;
    + uint32_t test_hwpt_id = 0;
    +
    + if (self->device_id) {
    + /* Negative tests */
    + test_err_cmd_hwpt_alloc(ENOENT, self->ioas_id, self->device_id,
    + &test_hwpt_id);
    + test_err_cmd_hwpt_alloc(EINVAL, self->device_id,
    + self->device_id, &test_hwpt_id);
    +
    + /* Allocate two nested hwpts sharing one common parent hwpt */
    + test_cmd_hwpt_alloc(self->device_id, self->ioas_id,
    + &parent_hwpt_id);
    +
    + test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id,
    + &nested_hwpt_id[0]);
    + test_cmd_hwpt_alloc_nested(self->device_id, parent_hwpt_id,
    + &nested_hwpt_id[1]);
    +
    + /* Negative test: a nested hwpt on top of a nested hwpt */
    + test_err_cmd_hwpt_alloc_nested(EINVAL, self->device_id,
    + nested_hwpt_id[0],
    + &test_hwpt_id);
    + /* 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);
    + } else {
    + test_err_cmd_hwpt_alloc(ENOENT, self->device_id, self->ioas_id,
    + &parent_hwpt_id);
    + test_err_cmd_hwpt_alloc_nested(ENOENT, self->device_id,
    + parent_hwpt_id,
    + &nested_hwpt_id[0]);
    + test_err_cmd_hwpt_alloc_nested(ENOENT, self->device_id,
    + parent_hwpt_id,
    + &nested_hwpt_id[1]);
    + 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 */
    @@ -663,6 +758,8 @@ TEST_F(iommufd_ioas, access_pin)
    MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES);

    for (npages = 1; npages < BUFFER_SIZE / PAGE_SIZE; npages++) {
    + uint32_t new_hwpt_id = 0;
    + uint32_t mock_device_id;
    uint32_t mock_stdev_id;
    uint32_t mock_hwpt_id;

    @@ -696,12 +793,27 @@ TEST_F(iommufd_ioas, access_pin)
    _IOMMU_TEST_CMD(IOMMU_TEST_OP_ACCESS_PAGES),
    &access_cmd));
    test_cmd_mock_domain(self->ioas_id, &mock_stdev_id,
    - &mock_hwpt_id, NULL);
    + &mock_hwpt_id, &mock_device_id);
    check_map_cmd.id = mock_hwpt_id;
    + if (variant->new_hwpt) {
    + test_cmd_hwpt_alloc(mock_device_id, self->ioas_id,
    + &new_hwpt_id);
    + test_cmd_mock_domain_replace(mock_stdev_id,
    + new_hwpt_id);
    + check_map_cmd.id = new_hwpt_id;
    + } else {
    + check_map_cmd.id = mock_hwpt_id;
    + }
    ASSERT_EQ(0, ioctl(self->fd,
    _IOMMU_TEST_CMD(IOMMU_TEST_OP_MD_CHECK_MAP),
    &check_map_cmd));

    + if (variant->new_hwpt) {
    + /* Detach from the new hwpt for its destroy() */
    + test_cmd_mock_domain_replace(mock_stdev_id,
    + mock_hwpt_id);
    + test_ioctl_destroy(new_hwpt_id);
    + }
    test_ioctl_destroy(mock_stdev_id);
    test_cmd_destroy_access_pages(
    access_cmd.id,
    diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h
    index 8dced7ef9118..e2c26168ec89 100644
    --- a/tools/testing/selftests/iommu/iommufd_utils.h
    +++ b/tools/testing/selftests/iommu/iommufd_utils.h
    @@ -118,6 +118,42 @@ static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,

    #define test_cmd_hwpt_alloc(device_id, pt_id, hwpt_id) \
    ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, hwpt_id))
    +#define test_err_cmd_hwpt_alloc(_errno, device_id, pt_id, hwpt_id) \
    + EXPECT_ERRNO(_errno, _test_cmd_hwpt_alloc(self->fd, device_id, \
    + pt_id, hwpt_id))
    +
    +static int _test_cmd_hwpt_alloc_nested(int fd, __u32 device_id, __u32 parent_id,
    + __u32 *hwpt_id)
    +{
    + struct iommu_hwpt_selftest data = {
    + .flags = IOMMU_TEST_FLAG_NESTED,
    + .test_config = IOMMU_TEST_IOTLB_DEFAULT,
    + };
    + struct iommu_hwpt_alloc cmd = {
    + .size = sizeof(cmd),
    + .dev_id = device_id,
    + .pt_id = parent_id,
    + .hwpt_type = IOMMU_HWPT_TYPE_SELFTTEST,
    + .data_len = sizeof(data),
    + .data_uptr = (uint64_t)&data,
    + };
    + int ret;
    +
    + ret = ioctl(fd, IOMMU_HWPT_ALLOC, &cmd);
    + if (ret)
    + return ret;
    + if (hwpt_id)
    + *hwpt_id = cmd.out_hwpt_id;
    + return 0;
    +}
    +
    +#define test_cmd_hwpt_alloc_nested(device_id, parent_id, hwpt_id) \
    + ASSERT_EQ(0, _test_cmd_hwpt_alloc_nested(self->fd, device_id, \
    + parent_id, hwpt_id))
    +#define test_err_cmd_hwpt_alloc_nested(_errno, device_id, parent_id, hwpt_id) \
    + EXPECT_ERRNO(_errno, \
    + _test_cmd_hwpt_alloc_nested(self->fd, device_id, \
    + parent_id, hwpt_id))

    static int _test_cmd_access_replace_ioas(int fd, __u32 access_id,
    unsigned int ioas_id)
    --
    2.34.1
    \
     
     \ /
      Last update: 2023-05-11 16:43    [W:3.050 / U:0.140 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site