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

iommufd/selftest: Test IOMMU_HWPT_SET_DIRTY_TRACKING

mainline inclusion
from mainline-v6.7-rc1
commit 7adf267d66d1d737ea8318976fd1ce93733fd3a4
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/?7adf267d66d1d737ea8318976fd1ce93733fd3a4

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

Change mock_domain to supporting dirty tracking and add tests to exercise
the new SET_DIRTY_TRACKING API in the iommufd_dirty_tracking selftest
fixture.

Intel-SIG: 7adf267d66d1 iommufd/selftest: Test IOMMU_HWPT_SET_DIRTY_TRACKING
Backport IOMMUFD Dirty Tracking

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


Signed-off-by: default avatarJoao Martins <joao.m.martins@oracle.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.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 d8086722
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ static struct platform_device *selftest_iommu_dev;
size_t iommufd_test_memory_limit = 65536;

enum {
	MOCK_DIRTY_TRACK = 1,
	MOCK_IO_PAGE_SIZE = PAGE_SIZE / 2,

	/*
@@ -86,6 +87,7 @@ void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,
}

struct mock_iommu_domain {
	unsigned long flags;
	struct iommu_domain domain;
	struct xarray pfns;
};
@@ -155,6 +157,20 @@ static void *mock_domain_hw_info(struct device *dev, u32 *length, u32 *type)
static int mock_domain_set_dirty_tracking(struct iommu_domain *domain,
					  bool enable)
{
	struct mock_iommu_domain *mock =
		container_of(domain, struct mock_iommu_domain, domain);
	unsigned long flags = mock->flags;

	if (enable && !domain->dirty_ops)
		return -EINVAL;

	/* No change? */
	if (!(enable ^ !!(flags & MOCK_DIRTY_TRACK)))
		return 0;

	flags = (enable ? flags | MOCK_DIRTY_TRACK : flags & ~MOCK_DIRTY_TRACK);

	mock->flags = flags;
	return 0;
}

+15 −0
Original line number Diff line number Diff line
@@ -1482,6 +1482,21 @@ TEST_F(iommufd_dirty_tracking, enforce_dirty)
	test_ioctl_destroy(stddev_id);
}

TEST_F(iommufd_dirty_tracking, set_dirty_tracking)
{
	uint32_t stddev_id;
	uint32_t hwpt_id;

	test_cmd_hwpt_alloc(self->idev_id, self->ioas_id,
			    IOMMU_HWPT_ALLOC_DIRTY_TRACKING, &hwpt_id);
	test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
	test_cmd_set_dirty_tracking(hwpt_id, true);
	test_cmd_set_dirty_tracking(hwpt_id, false);

	test_ioctl_destroy(stddev_id);
	test_ioctl_destroy(hwpt_id);
}

/* VFIO compatibility IOCTLs */

TEST_F(iommufd, simple_ioctls)
+17 −0
Original line number Diff line number Diff line
@@ -179,6 +179,23 @@ static int _test_cmd_access_replace_ioas(int fd, __u32 access_id,
#define test_cmd_access_replace_ioas(access_id, ioas_id) \
	ASSERT_EQ(0, _test_cmd_access_replace_ioas(self->fd, access_id, ioas_id))

static int _test_cmd_set_dirty_tracking(int fd, __u32 hwpt_id, bool enabled)
{
	struct iommu_hwpt_set_dirty_tracking cmd = {
		.size = sizeof(cmd),
		.flags = enabled ? IOMMU_HWPT_DIRTY_TRACKING_ENABLE : 0,
		.hwpt_id = hwpt_id,
	};
	int ret;

	ret = ioctl(fd, IOMMU_HWPT_SET_DIRTY_TRACKING, &cmd);
	if (ret)
		return -errno;
	return 0;
}
#define test_cmd_set_dirty_tracking(hwpt_id, enabled) \
	ASSERT_EQ(0, _test_cmd_set_dirty_tracking(self->fd, hwpt_id, enabled))

static int _test_cmd_create_access(int fd, unsigned int ioas_id,
				   __u32 *access_id, unsigned int flags)
{