Message ID | 20231117130717.19875-7-yi.l.liu@intel.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | iommufd: Add nesting infrastructure (part 2/2) | expand |
On Fri, Nov 17, 2023 at 05:07:17AM -0800, Yi Liu wrote: > From: Nicolin Chen <nicolinc@nvidia.com> > > Add test cases for the IOMMU_HWPT_INVALIDATE ioctl and verify it by using > the new IOMMU_TEST_OP_MD_CHECK_IOTLB. > > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> > Signed-off-by: Yi Liu <yi.l.liu@intel.com> > --- > tools/testing/selftests/iommu/iommufd.c | 71 +++++++++++++++++++ > tools/testing/selftests/iommu/iommufd_utils.h | 39 ++++++++++ > 2 files changed, 110 insertions(+) > > diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c > index c8763b880a16..2781d5bc6309 100644 > --- a/tools/testing/selftests/iommu/iommufd.c > +++ b/tools/testing/selftests/iommu/iommufd.c > @@ -116,6 +116,7 @@ TEST_F(iommufd, cmd_length) > TEST_LENGTH(iommu_destroy, IOMMU_DESTROY, id); > TEST_LENGTH(iommu_hw_info, IOMMU_GET_HW_INFO, __reserved); > TEST_LENGTH(iommu_hwpt_alloc, IOMMU_HWPT_ALLOC, __reserved); > + TEST_LENGTH(iommu_hwpt_invalidate, IOMMU_HWPT_INVALIDATE, out_driver_error_code); > TEST_LENGTH(iommu_ioas_alloc, IOMMU_IOAS_ALLOC, out_ioas_id); > TEST_LENGTH(iommu_ioas_iova_ranges, IOMMU_IOAS_IOVA_RANGES, > out_iova_alignment); > @@ -271,7 +272,9 @@ TEST_F(iommufd_ioas, alloc_hwpt_nested) > struct iommu_hwpt_selftest data = { > .iotlb = IOMMU_TEST_IOTLB_DEFAULT, > }; > + struct iommu_hwpt_invalidate_selftest inv_reqs[2] = {0}; Don't use {0} Jason
On 2023/12/7 02:19, Jason Gunthorpe wrote: > On Fri, Nov 17, 2023 at 05:07:17AM -0800, Yi Liu wrote: >> From: Nicolin Chen <nicolinc@nvidia.com> >> >> Add test cases for the IOMMU_HWPT_INVALIDATE ioctl and verify it by using >> the new IOMMU_TEST_OP_MD_CHECK_IOTLB. >> >> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> >> Signed-off-by: Yi Liu <yi.l.liu@intel.com> >> --- >> tools/testing/selftests/iommu/iommufd.c | 71 +++++++++++++++++++ >> tools/testing/selftests/iommu/iommufd_utils.h | 39 ++++++++++ >> 2 files changed, 110 insertions(+) >> >> diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c >> index c8763b880a16..2781d5bc6309 100644 >> --- a/tools/testing/selftests/iommu/iommufd.c >> +++ b/tools/testing/selftests/iommu/iommufd.c >> @@ -116,6 +116,7 @@ TEST_F(iommufd, cmd_length) >> TEST_LENGTH(iommu_destroy, IOMMU_DESTROY, id); >> TEST_LENGTH(iommu_hw_info, IOMMU_GET_HW_INFO, __reserved); >> TEST_LENGTH(iommu_hwpt_alloc, IOMMU_HWPT_ALLOC, __reserved); >> + TEST_LENGTH(iommu_hwpt_invalidate, IOMMU_HWPT_INVALIDATE, out_driver_error_code); >> TEST_LENGTH(iommu_ioas_alloc, IOMMU_IOAS_ALLOC, out_ioas_id); >> TEST_LENGTH(iommu_ioas_iova_ranges, IOMMU_IOAS_IOVA_RANGES, >> out_iova_alignment); >> @@ -271,7 +272,9 @@ TEST_F(iommufd_ioas, alloc_hwpt_nested) >> struct iommu_hwpt_selftest data = { >> .iotlb = IOMMU_TEST_IOTLB_DEFAULT, >> }; >> + struct iommu_hwpt_invalidate_selftest inv_reqs[2] = {0}; > > Don't use {0} sure. I'll use memset then.
On Mon, Dec 11, 2023 at 07:28:42PM +0800, Yi Liu wrote: > On 2023/12/7 02:19, Jason Gunthorpe wrote: > > On Fri, Nov 17, 2023 at 05:07:17AM -0800, Yi Liu wrote: > > > From: Nicolin Chen <nicolinc@nvidia.com> > > > > > > Add test cases for the IOMMU_HWPT_INVALIDATE ioctl and verify it by using > > > the new IOMMU_TEST_OP_MD_CHECK_IOTLB. > > > > > > Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> > > > Signed-off-by: Yi Liu <yi.l.liu@intel.com> > > > --- > > > tools/testing/selftests/iommu/iommufd.c | 71 +++++++++++++++++++ > > > tools/testing/selftests/iommu/iommufd_utils.h | 39 ++++++++++ > > > 2 files changed, 110 insertions(+) > > > > > > diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c > > > index c8763b880a16..2781d5bc6309 100644 > > > --- a/tools/testing/selftests/iommu/iommufd.c > > > +++ b/tools/testing/selftests/iommu/iommufd.c > > > @@ -116,6 +116,7 @@ TEST_F(iommufd, cmd_length) > > > TEST_LENGTH(iommu_destroy, IOMMU_DESTROY, id); > > > TEST_LENGTH(iommu_hw_info, IOMMU_GET_HW_INFO, __reserved); > > > TEST_LENGTH(iommu_hwpt_alloc, IOMMU_HWPT_ALLOC, __reserved); > > > + TEST_LENGTH(iommu_hwpt_invalidate, IOMMU_HWPT_INVALIDATE, out_driver_error_code); > > > TEST_LENGTH(iommu_ioas_alloc, IOMMU_IOAS_ALLOC, out_ioas_id); > > > TEST_LENGTH(iommu_ioas_iova_ranges, IOMMU_IOAS_IOVA_RANGES, > > > out_iova_alignment); > > > @@ -271,7 +272,9 @@ TEST_F(iommufd_ioas, alloc_hwpt_nested) > > > struct iommu_hwpt_selftest data = { > > > .iotlb = IOMMU_TEST_IOTLB_DEFAULT, > > > }; > > > + struct iommu_hwpt_invalidate_selftest inv_reqs[2] = {0}; > > > > Don't use {0} > > sure. I'll use memset then. Just use = {} Jason
diff --git a/tools/testing/selftests/iommu/iommufd.c b/tools/testing/selftests/iommu/iommufd.c index c8763b880a16..2781d5bc6309 100644 --- a/tools/testing/selftests/iommu/iommufd.c +++ b/tools/testing/selftests/iommu/iommufd.c @@ -116,6 +116,7 @@ TEST_F(iommufd, cmd_length) TEST_LENGTH(iommu_destroy, IOMMU_DESTROY, id); TEST_LENGTH(iommu_hw_info, IOMMU_GET_HW_INFO, __reserved); TEST_LENGTH(iommu_hwpt_alloc, IOMMU_HWPT_ALLOC, __reserved); + TEST_LENGTH(iommu_hwpt_invalidate, IOMMU_HWPT_INVALIDATE, out_driver_error_code); TEST_LENGTH(iommu_ioas_alloc, IOMMU_IOAS_ALLOC, out_ioas_id); TEST_LENGTH(iommu_ioas_iova_ranges, IOMMU_IOAS_IOVA_RANGES, out_iova_alignment); @@ -271,7 +272,9 @@ TEST_F(iommufd_ioas, alloc_hwpt_nested) struct iommu_hwpt_selftest data = { .iotlb = IOMMU_TEST_IOTLB_DEFAULT, }; + struct iommu_hwpt_invalidate_selftest inv_reqs[2] = {0}; uint32_t nested_hwpt_id[2] = {}; + uint32_t num_inv, driver_error; uint32_t parent_hwpt_id = 0; uint32_t parent_hwpt_id_not_work = 0; uint32_t test_hwpt_id = 0; @@ -344,6 +347,74 @@ TEST_F(iommufd_ioas, alloc_hwpt_nested) EXPECT_ERRNO(EBUSY, _test_ioctl_destroy(self->fd, parent_hwpt_id)); + /* hwpt_invalidate only supports a user-managed hwpt (nested) */ + num_inv = 1; + test_err_hwpt_invalidate(ENOENT, parent_hwpt_id, inv_reqs, + IOMMU_HWPT_DATA_SELFTEST, + sizeof(*inv_reqs), &num_inv, NULL); + /* Negative test: wrong data type */ + num_inv = 1; + test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs, + IOMMU_HWPT_DATA_NONE, + sizeof(*inv_reqs), &num_inv, + &driver_error); + /* Negative test: structure size sanity */ + num_inv = 1; + test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs, + IOMMU_HWPT_DATA_SELFTEST, + sizeof(*inv_reqs) + 1, &num_inv, + &driver_error); + assert(driver_error == IOMMU_TEST_INVALIDATE_ERR_FETCH); + + num_inv = 1; + test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs, + IOMMU_HWPT_DATA_SELFTEST, + 1, &num_inv, &driver_error); + assert(driver_error == IOMMU_TEST_INVALIDATE_ERR_FETCH); + + /* Invalidate the 1st iotlb entry but fail the 2nd request */ + num_inv = 2; + inv_reqs[0].iotlb_id = 0; + inv_reqs[1].iotlb_id = MOCK_NESTED_DOMAIN_IOTLB_ID_MAX + 1; + test_err_hwpt_invalidate(EINVAL, nested_hwpt_id[0], inv_reqs, + IOMMU_HWPT_DATA_SELFTEST, + sizeof(*inv_reqs), &num_inv, + &driver_error); + assert(num_inv == 1); + assert(driver_error == IOMMU_TEST_INVALIDATE_ERR_REQ); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 0, 0); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 1, + IOMMU_TEST_IOTLB_DEFAULT); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 2, + IOMMU_TEST_IOTLB_DEFAULT); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 3, + IOMMU_TEST_IOTLB_DEFAULT); + + /* Invalidate the 2nd iotlb entry and verify */ + num_inv = 1; + inv_reqs[0].iotlb_id = 1; + test_cmd_hwpt_invalidate(nested_hwpt_id[0], inv_reqs, + sizeof(*inv_reqs), &num_inv); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 0, 0); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 1, 0); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 2, + IOMMU_TEST_IOTLB_DEFAULT); + test_cmd_hwpt_check_iotlb(nested_hwpt_id[0], 3, + IOMMU_TEST_IOTLB_DEFAULT); + /* Invalidate the 3rd and 4th iotlb entries and verify */ + num_inv = 2; + inv_reqs[0].iotlb_id = 2; + inv_reqs[1].iotlb_id = 3; + test_cmd_hwpt_invalidate(nested_hwpt_id[0], inv_reqs, + sizeof(*inv_reqs), &num_inv); + test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[0], 0); + /* Invalidate all iotlb entries for nested_hwpt_id[1] and verify */ + num_inv = 1; + inv_reqs[0].flags = IOMMU_TEST_INVALIDATE_ALL; + test_cmd_hwpt_invalidate(nested_hwpt_id[1], inv_reqs, + sizeof(*inv_reqs), &num_inv); + test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[1], 0); + /* 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, diff --git a/tools/testing/selftests/iommu/iommufd_utils.h b/tools/testing/selftests/iommu/iommufd_utils.h index 69561ba9e7aa..d4a169a2278e 100644 --- a/tools/testing/selftests/iommu/iommufd_utils.h +++ b/tools/testing/selftests/iommu/iommufd_utils.h @@ -219,6 +219,45 @@ static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id, test_cmd_hwpt_check_iotlb(hwpt_id, i, expected); \ }) +static int _test_cmd_hwpt_invalidate(int fd, __u32 hwpt_id, void *reqs, + uint32_t req_type, uint32_t lreq, + uint32_t *nreqs, uint32_t *driver_error) +{ + struct iommu_hwpt_invalidate cmd = { + .size = sizeof(cmd), + .hwpt_id = hwpt_id, + .req_type = req_type, + .reqs_uptr = (uint64_t)reqs, + .req_len = lreq, + .req_num = *nreqs, + }; + int rc = ioctl(fd, IOMMU_HWPT_INVALIDATE, &cmd); + *nreqs = cmd.req_num; + if (driver_error) + *driver_error = cmd.out_driver_error_code; + return rc; +} + +#define test_cmd_hwpt_invalidate(hwpt_id, reqs, lreq, nreqs) \ + ({ \ + uint32_t error, num = *nreqs; \ + ASSERT_EQ(0, \ + _test_cmd_hwpt_invalidate(self->fd, hwpt_id, reqs, \ + IOMMU_HWPT_DATA_SELFTEST, \ + lreq, nreqs, &error)); \ + assert(num == *nreqs); \ + assert(error == 0); \ + }) +#define test_err_hwpt_invalidate(_errno, hwpt_id, reqs, req_type, lreq, \ + nreqs, driver_error) \ + ({ \ + EXPECT_ERRNO(_errno, \ + _test_cmd_hwpt_invalidate(self->fd, hwpt_id, \ + reqs, req_type, \ + lreq, nreqs, \ + driver_error)); \ + }) + static int _test_cmd_access_replace_ioas(int fd, __u32 access_id, unsigned int ioas_id) {