Commit 82fe01e5 authored by Joao Martins's avatar Joao Martins Committed by Jason Zeng
Browse files

iommufd/selftest: Test out_capabilities in IOMMU_GET_HW_INFO

mainline inclusion
from mainline-v6.7-rc1
commit ae36fe70cea4d7c177452ab41e6734fa3cbd4ad8
category: feature
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I8Y6AM
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?ae36fe70cea4d7c177452ab41e6734fa3cbd4ad8

--------------------------------

Enumerate the capabilities from the mock device and test whether it
advertises as expected. Include it as part of the iommufd_dirty_tracking
fixture.

Intel-SIG:  ae36fe70cea4 iommufd/selftest: Test out_capabilities in IOMMU_GET_HW_INFO
Backport IOMMUFD Dirty Tracking

Link: https://lore.kernel.org/r/20231024135109.73787-18-joao.m.martins@oracle.com


Signed-off-by: default avatarJoao Martins <joao.m.martins@oracle.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
[ jz: amend commit log ]
Signed-off-by: default avatarJason Zeng <jason.zeng@intel.com>
parent fc6f6a24
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -376,7 +376,18 @@ static phys_addr_t mock_domain_iova_to_phys(struct iommu_domain *domain,

static bool mock_domain_capable(struct device *dev, enum iommu_cap cap)
{
	return cap == IOMMU_CAP_CACHE_COHERENCY;
	struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);

	switch (cap) {
	case IOMMU_CAP_CACHE_COHERENCY:
		return true;
	case IOMMU_CAP_DIRTY_TRACKING:
		return !(mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY);
	default:
		break;
	}

	return false;
}

static void mock_domain_set_plaform_dma_ops(struct device *dev)
+17 −0
Original line number Diff line number Diff line
@@ -1563,6 +1563,23 @@ TEST_F(iommufd_dirty_tracking, set_dirty_tracking)
	test_ioctl_destroy(hwpt_id);
}

TEST_F(iommufd_dirty_tracking, device_dirty_capability)
{
	uint32_t caps = 0;
	uint32_t stddev_id;
	uint32_t hwpt_id;

	test_cmd_hwpt_alloc(self->idev_id, self->ioas_id, 0, &hwpt_id);
	test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
	test_cmd_get_hw_capabilities(self->idev_id, caps,
				     IOMMU_HW_CAP_DIRTY_TRACKING);
	ASSERT_EQ(IOMMU_HW_CAP_DIRTY_TRACKING,
		  caps & IOMMU_HW_CAP_DIRTY_TRACKING);

	test_ioctl_destroy(stddev_id);
	test_ioctl_destroy(hwpt_id);
}

TEST_F(iommufd_dirty_tracking, get_dirty_bitmap)
{
	uint32_t stddev_id;
+1 −1
Original line number Diff line number Diff line
@@ -612,7 +612,7 @@ TEST_FAIL_NTH(basic_fail_nth, device)
				  &idev_id))
		return -1;

	if (_test_cmd_get_hw_info(self->fd, idev_id, &info, sizeof(info)))
	if (_test_cmd_get_hw_info(self->fd, idev_id, &info, sizeof(info), NULL))
		return -1;

	if (_test_cmd_hwpt_alloc(self->fd, idev_id, ioas_id, 0, &hwpt_id))
+15 −9
Original line number Diff line number Diff line
@@ -535,8 +535,8 @@ static void teardown_iommufd(int fd, struct __test_metadata *_metadata)
#endif

/* @data can be NULL */
static int _test_cmd_get_hw_info(int fd, __u32 device_id,
				 void *data, size_t data_len)
static int _test_cmd_get_hw_info(int fd, __u32 device_id, void *data,
				 size_t data_len, uint32_t *capabilities)
{
	struct iommu_test_hw_info *info = (struct iommu_test_hw_info *)data;
	struct iommu_hw_info cmd = {
@@ -544,6 +544,7 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id,
		.dev_id = device_id,
		.data_len = data_len,
		.data_uptr = (uint64_t)data,
		.out_capabilities = 0,
	};
	int ret;

@@ -580,14 +581,19 @@ static int _test_cmd_get_hw_info(int fd, __u32 device_id,
			assert(!info->flags);
	}

	if (capabilities)
		*capabilities = cmd.out_capabilities;

	return 0;
}

#define test_cmd_get_hw_info(device_id, data, data_len)               \
	ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, \
					   data, data_len))
	ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, data, \
					   data_len, NULL))

#define test_err_get_hw_info(_errno, device_id, data, data_len)               \
	EXPECT_ERRNO(_errno,                                    \
		     _test_cmd_get_hw_info(self->fd, device_id, \
					   data, data_len))
	EXPECT_ERRNO(_errno, _test_cmd_get_hw_info(self->fd, device_id, data, \
						   data_len, NULL))

#define test_cmd_get_hw_capabilities(device_id, caps, mask) \
	ASSERT_EQ(0, _test_cmd_get_hw_info(self->fd, device_id, NULL, 0, &caps))