mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 05:41:55 +00:00
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:
parent
ac8691203c
commit
e1fa6640d5
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user