Commit e1fa6640 authored by Nicolin Chen's avatar Nicolin Chen Committed by Jason Gunthorpe
Browse files

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: default avatarKevin Tian <kevin.tian@intel.com>
Signed-off-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Signed-off-by: default avatarYi Liu <yi.l.liu@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent ac869120
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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;
};
+26 −0
Original line number Diff line number Diff line
@@ -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);
+4 −0
Original line number Diff line number Diff line
@@ -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,
+24 −0
Original line number Diff line number Diff line
@@ -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)
{