Skip to content

Commit 7156cd9

Browse files
nicolincjgunthorpe
authored andcommitted
iommufd/selftest: Add IOMMU_VIOMMU_ALLOC test coverage
Add a new iommufd_viommu FIXTURE and setup it up with a vIOMMU object. Any new vIOMMU feature will be added as a TEST_F under that. Link: https://patch.msgid.link/r/abe267c9d004b29cb1712ceba2f378209d4b7e01.1730836219.git.nicolinc@nvidia.com Reviewed-by: Kevin Tian <[email protected]> Signed-off-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent db70827 commit 7156cd9

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

tools/testing/selftests/iommu/iommufd.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ TEST_F(iommufd, cmd_length)
133133
TEST_LENGTH(iommu_option, IOMMU_OPTION, val64);
134134
TEST_LENGTH(iommu_vfio_ioas, IOMMU_VFIO_IOAS, __reserved);
135135
TEST_LENGTH(iommu_ioas_map_file, IOMMU_IOAS_MAP_FILE, iova);
136+
TEST_LENGTH(iommu_viommu_alloc, IOMMU_VIOMMU_ALLOC, out_viommu_id);
136137
#undef TEST_LENGTH
137138
}
138139

@@ -2480,4 +2481,140 @@ TEST_F(vfio_compat_mock_domain, huge_map)
24802481
}
24812482
}
24822483

2484+
FIXTURE(iommufd_viommu)
2485+
{
2486+
int fd;
2487+
uint32_t ioas_id;
2488+
uint32_t stdev_id;
2489+
uint32_t hwpt_id;
2490+
uint32_t nested_hwpt_id;
2491+
uint32_t device_id;
2492+
uint32_t viommu_id;
2493+
};
2494+
2495+
FIXTURE_VARIANT(iommufd_viommu)
2496+
{
2497+
unsigned int viommu;
2498+
};
2499+
2500+
FIXTURE_SETUP(iommufd_viommu)
2501+
{
2502+
self->fd = open("/dev/iommu", O_RDWR);
2503+
ASSERT_NE(-1, self->fd);
2504+
test_ioctl_ioas_alloc(&self->ioas_id);
2505+
test_ioctl_set_default_memory_limit();
2506+
2507+
if (variant->viommu) {
2508+
struct iommu_hwpt_selftest data = {
2509+
.iotlb = IOMMU_TEST_IOTLB_DEFAULT,
2510+
};
2511+
2512+
test_cmd_mock_domain(self->ioas_id, &self->stdev_id, NULL,
2513+
&self->device_id);
2514+
2515+
/* Allocate a nesting parent hwpt */
2516+
test_cmd_hwpt_alloc(self->device_id, self->ioas_id,
2517+
IOMMU_HWPT_ALLOC_NEST_PARENT,
2518+
&self->hwpt_id);
2519+
2520+
/* Allocate a vIOMMU taking refcount of the parent hwpt */
2521+
test_cmd_viommu_alloc(self->device_id, self->hwpt_id,
2522+
IOMMU_VIOMMU_TYPE_SELFTEST,
2523+
&self->viommu_id);
2524+
2525+
/* Allocate a regular nested hwpt */
2526+
test_cmd_hwpt_alloc_nested(self->device_id, self->viommu_id, 0,
2527+
&self->nested_hwpt_id,
2528+
IOMMU_HWPT_DATA_SELFTEST, &data,
2529+
sizeof(data));
2530+
}
2531+
}
2532+
2533+
FIXTURE_TEARDOWN(iommufd_viommu)
2534+
{
2535+
teardown_iommufd(self->fd, _metadata);
2536+
}
2537+
2538+
FIXTURE_VARIANT_ADD(iommufd_viommu, no_viommu)
2539+
{
2540+
.viommu = 0,
2541+
};
2542+
2543+
FIXTURE_VARIANT_ADD(iommufd_viommu, mock_viommu)
2544+
{
2545+
.viommu = 1,
2546+
};
2547+
2548+
TEST_F(iommufd_viommu, viommu_auto_destroy)
2549+
{
2550+
}
2551+
2552+
TEST_F(iommufd_viommu, viommu_negative_tests)
2553+
{
2554+
uint32_t device_id = self->device_id;
2555+
uint32_t ioas_id = self->ioas_id;
2556+
uint32_t hwpt_id;
2557+
2558+
if (self->device_id) {
2559+
/* Negative test -- invalid hwpt (hwpt_id=0) */
2560+
test_err_viommu_alloc(ENOENT, device_id, 0,
2561+
IOMMU_VIOMMU_TYPE_SELFTEST, NULL);
2562+
2563+
/* Negative test -- not a nesting parent hwpt */
2564+
test_cmd_hwpt_alloc(device_id, ioas_id, 0, &hwpt_id);
2565+
test_err_viommu_alloc(EINVAL, device_id, hwpt_id,
2566+
IOMMU_VIOMMU_TYPE_SELFTEST, NULL);
2567+
test_ioctl_destroy(hwpt_id);
2568+
2569+
/* Negative test -- unsupported viommu type */
2570+
test_err_viommu_alloc(EOPNOTSUPP, device_id, self->hwpt_id,
2571+
0xdead, NULL);
2572+
EXPECT_ERRNO(EBUSY,
2573+
_test_ioctl_destroy(self->fd, self->hwpt_id));
2574+
EXPECT_ERRNO(EBUSY,
2575+
_test_ioctl_destroy(self->fd, self->viommu_id));
2576+
} else {
2577+
test_err_viommu_alloc(ENOENT, self->device_id, self->hwpt_id,
2578+
IOMMU_VIOMMU_TYPE_SELFTEST, NULL);
2579+
}
2580+
}
2581+
2582+
TEST_F(iommufd_viommu, viommu_alloc_nested_iopf)
2583+
{
2584+
struct iommu_hwpt_selftest data = {
2585+
.iotlb = IOMMU_TEST_IOTLB_DEFAULT,
2586+
};
2587+
uint32_t viommu_id = self->viommu_id;
2588+
uint32_t dev_id = self->device_id;
2589+
uint32_t iopf_hwpt_id;
2590+
uint32_t fault_id;
2591+
uint32_t fault_fd;
2592+
2593+
if (self->device_id) {
2594+
test_ioctl_fault_alloc(&fault_id, &fault_fd);
2595+
test_err_hwpt_alloc_iopf(
2596+
ENOENT, dev_id, viommu_id, UINT32_MAX,
2597+
IOMMU_HWPT_FAULT_ID_VALID, &iopf_hwpt_id,
2598+
IOMMU_HWPT_DATA_SELFTEST, &data, sizeof(data));
2599+
test_err_hwpt_alloc_iopf(
2600+
EOPNOTSUPP, dev_id, viommu_id, fault_id,
2601+
IOMMU_HWPT_FAULT_ID_VALID | (1 << 31), &iopf_hwpt_id,
2602+
IOMMU_HWPT_DATA_SELFTEST, &data, sizeof(data));
2603+
test_cmd_hwpt_alloc_iopf(
2604+
dev_id, viommu_id, fault_id, IOMMU_HWPT_FAULT_ID_VALID,
2605+
&iopf_hwpt_id, IOMMU_HWPT_DATA_SELFTEST, &data,
2606+
sizeof(data));
2607+
2608+
test_cmd_mock_domain_replace(self->stdev_id, iopf_hwpt_id);
2609+
EXPECT_ERRNO(EBUSY,
2610+
_test_ioctl_destroy(self->fd, iopf_hwpt_id));
2611+
test_cmd_trigger_iopf(dev_id, fault_fd);
2612+
2613+
test_cmd_mock_domain_replace(self->stdev_id, self->ioas_id);
2614+
test_ioctl_destroy(iopf_hwpt_id);
2615+
close(fault_fd);
2616+
test_ioctl_destroy(fault_id);
2617+
}
2618+
}
2619+
24832620
TEST_HARNESS_MAIN

tools/testing/selftests/iommu/iommufd_fail_nth.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ TEST_FAIL_NTH(basic_fail_nth, device)
621621
uint32_t stdev_id;
622622
uint32_t idev_id;
623623
uint32_t hwpt_id;
624+
uint32_t viommu_id;
624625
__u64 iova;
625626

626627
self->fd = open("/dev/iommu", O_RDWR);
@@ -663,6 +664,16 @@ TEST_FAIL_NTH(basic_fail_nth, device)
663664

664665
if (_test_cmd_mock_domain_replace(self->fd, stdev_id, hwpt_id, NULL))
665666
return -1;
667+
668+
if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0,
669+
IOMMU_HWPT_ALLOC_NEST_PARENT, &hwpt_id,
670+
IOMMU_HWPT_DATA_NONE, 0, 0))
671+
return -1;
672+
673+
if (_test_cmd_viommu_alloc(self->fd, idev_id, hwpt_id,
674+
IOMMU_VIOMMU_TYPE_SELFTEST, 0, &viommu_id))
675+
return -1;
676+
666677
return 0;
667678
}
668679

tools/testing/selftests/iommu/iommufd_utils.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,3 +819,31 @@ static int _test_cmd_trigger_iopf(int fd, __u32 device_id, __u32 fault_fd)
819819

820820
#define test_cmd_trigger_iopf(device_id, fault_fd) \
821821
ASSERT_EQ(0, _test_cmd_trigger_iopf(self->fd, device_id, fault_fd))
822+
823+
static int _test_cmd_viommu_alloc(int fd, __u32 device_id, __u32 hwpt_id,
824+
__u32 type, __u32 flags, __u32 *viommu_id)
825+
{
826+
struct iommu_viommu_alloc cmd = {
827+
.size = sizeof(cmd),
828+
.flags = flags,
829+
.type = type,
830+
.dev_id = device_id,
831+
.hwpt_id = hwpt_id,
832+
};
833+
int ret;
834+
835+
ret = ioctl(fd, IOMMU_VIOMMU_ALLOC, &cmd);
836+
if (ret)
837+
return ret;
838+
if (viommu_id)
839+
*viommu_id = cmd.out_viommu_id;
840+
return 0;
841+
}
842+
843+
#define test_cmd_viommu_alloc(device_id, hwpt_id, type, viommu_id) \
844+
ASSERT_EQ(0, _test_cmd_viommu_alloc(self->fd, device_id, hwpt_id, \
845+
type, 0, viommu_id))
846+
#define test_err_viommu_alloc(_errno, device_id, hwpt_id, type, viommu_id) \
847+
EXPECT_ERRNO(_errno, \
848+
_test_cmd_viommu_alloc(self->fd, device_id, hwpt_id, \
849+
type, 0, viommu_id))

0 commit comments

Comments
 (0)