iommufd/selftest: Add IOMMU_TEST_OP_MD_CHECK_IOTLB test op

Allow to test whether IOTLB has been invalidated or not.

Link: https://lore.kernel.org/r/20240111041015.47920-6-yi.l.liu@intel.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
This commit is contained in:
Nicolin Chen 2024-01-10 20:10:12 -08:00 committed by Jason Gunthorpe
parent ac8691203c
commit e1fa6640d5
4 changed files with 59 additions and 0 deletions

View file

@ -21,6 +21,7 @@ enum {
IOMMU_TEST_OP_ACCESS_REPLACE_IOAS,
IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS,
IOMMU_TEST_OP_DIRTY,
IOMMU_TEST_OP_MD_CHECK_IOTLB,
};
enum {
@ -121,6 +122,10 @@ struct iommu_test_cmd {
__aligned_u64 uptr;
__aligned_u64 out_nr_dirty;
} dirty;
struct {
__u32 id;
__u32 iotlb;
} check_iotlb;
};
__u32 last;
};

View file

@ -843,6 +843,28 @@ static int iommufd_test_md_check_refs(struct iommufd_ucmd *ucmd,
return 0;
}
static int iommufd_test_md_check_iotlb(struct iommufd_ucmd *ucmd,
u32 mockpt_id, unsigned int iotlb_id,
u32 iotlb)
{
struct mock_iommu_domain_nested *mock_nested;
struct iommufd_hw_pagetable *hwpt;
int rc = 0;
hwpt = get_md_pagetable_nested(ucmd, mockpt_id, &mock_nested);
if (IS_ERR(hwpt))
return PTR_ERR(hwpt);
mock_nested = container_of(hwpt->domain,
struct mock_iommu_domain_nested, domain);
if (iotlb_id > MOCK_NESTED_DOMAIN_IOTLB_ID_MAX ||
mock_nested->iotlb[iotlb_id] != iotlb)
rc = -EINVAL;
iommufd_put_object(ucmd->ictx, &hwpt->obj);
return rc;
}
struct selftest_access {
struct iommufd_access *access;
struct file *file;
@ -1324,6 +1346,10 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
return iommufd_test_md_check_refs(
ucmd, u64_to_user_ptr(cmd->check_refs.uptr),
cmd->check_refs.length, cmd->check_refs.refs);
case IOMMU_TEST_OP_MD_CHECK_IOTLB:
return iommufd_test_md_check_iotlb(ucmd, cmd->id,
cmd->check_iotlb.id,
cmd->check_iotlb.iotlb);
case IOMMU_TEST_OP_CREATE_ACCESS:
return iommufd_test_create_access(ucmd, cmd->id,
cmd->create_access.flags);

View file

@ -330,6 +330,10 @@ TEST_F(iommufd_ioas, alloc_hwpt_nested)
&nested_hwpt_id[1],
IOMMU_HWPT_DATA_SELFTEST, &data,
sizeof(data));
test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[0],
IOMMU_TEST_IOTLB_DEFAULT);
test_cmd_hwpt_check_iotlb_all(nested_hwpt_id[1],
IOMMU_TEST_IOTLB_DEFAULT);
/* Negative test: a nested hwpt on top of a nested hwpt */
test_err_hwpt_alloc_nested(EINVAL, self->device_id,

View file

@ -195,6 +195,30 @@ static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,
_test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
hwpt_id, data_type, data, data_len))
#define test_cmd_hwpt_check_iotlb(hwpt_id, iotlb_id, expected) \
({ \
struct iommu_test_cmd test_cmd = { \
.size = sizeof(test_cmd), \
.op = IOMMU_TEST_OP_MD_CHECK_IOTLB, \
.id = hwpt_id, \
.check_iotlb = { \
.id = iotlb_id, \
.iotlb = expected, \
}, \
}; \
ASSERT_EQ(0, \
ioctl(self->fd, \
_IOMMU_TEST_CMD(IOMMU_TEST_OP_MD_CHECK_IOTLB), \
&test_cmd)); \
})
#define test_cmd_hwpt_check_iotlb_all(hwpt_id, expected) \
({ \
int i; \
for (i = 0; i < MOCK_NESTED_DOMAIN_IOTLB_NUM; i++) \
test_cmd_hwpt_check_iotlb(hwpt_id, i, expected); \
})
static int _test_cmd_access_replace_ioas(int fd, __u32 access_id,
unsigned int ioas_id)
{