@@ -21,6 +21,7 @@ static struct dentry *dbgfs_root;
size_t iommufd_test_memory_limit = 65536;
enum {
+ MOCK_DIRTY_TRACK = 1,
MOCK_IO_PAGE_SIZE = PAGE_SIZE / 2,
/*
@@ -83,6 +84,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;
};
@@ -283,6 +285,24 @@ static void mock_domain_set_plaform_dma_ops(struct device *dev)
*/
}
+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;
+
+ /* No change? */
+ if (!(enable ^ !!(flags & MOCK_DIRTY_TRACK)))
+ return -EINVAL;
+
+ flags = (enable ?
+ flags | MOCK_DIRTY_TRACK : flags & ~MOCK_DIRTY_TRACK);
+
+ mock->flags = flags;
+ return 0;
+}
+
static const struct iommu_ops mock_ops = {
.owner = THIS_MODULE,
.supported_flags = IOMMU_DOMAIN_F_ENFORCE_DIRTY,
@@ -297,6 +317,7 @@ static const struct iommu_ops mock_ops = {
.map_pages = mock_domain_map_pages,
.unmap_pages = mock_domain_unmap_pages,
.iova_to_phys = mock_domain_iova_to_phys,
+ .set_dirty_tracking = mock_domain_set_dirty_tracking,
},
};
@@ -1393,6 +1393,21 @@ TEST_F(iommufd_dirty_tracking, enforce_dirty)
test_ioctl_destroy(hwpt_id);
}
+TEST_F(iommufd_dirty_tracking, set_dirty)
+{
+ uint32_t stddev_id;
+ uint32_t hwpt_id;
+
+ test_cmd_hwpt_alloc(self->idev_id, self->ioas_id,
+ IOMMU_HWPT_ALLOC_ENFORCE_DIRTY, &hwpt_id);
+ test_cmd_mock_domain(hwpt_id, &stddev_id, NULL, NULL);
+ test_cmd_set_dirty(hwpt_id, true);
+ test_cmd_set_dirty(hwpt_id, false);
+
+ test_ioctl_destroy(stddev_id);
+ test_ioctl_destroy(hwpt_id);
+}
+
/* VFIO compatibility IOCTLs */
TEST_F(iommufd, simple_ioctls)
@@ -125,6 +125,24 @@ static int _test_cmd_hwpt_alloc(int fd, __u32 device_id, __u32 pt_id,
ASSERT_EQ(0, _test_cmd_hwpt_alloc(self->fd, device_id, pt_id, flags, \
hwpt_id))
+static int _test_cmd_set_dirty(int fd, __u32 hwpt_id, bool enabled)
+{
+ struct iommu_hwpt_set_dirty cmd = {
+ .size = sizeof(cmd),
+ .flags = enabled ? IOMMU_DIRTY_TRACKING_ENABLED :
+ IOMMU_DIRTY_TRACKING_DISABLED,
+ .hwpt_id = hwpt_id,
+ };
+ int ret;
+
+ ret = ioctl(fd, IOMMU_HWPT_SET_DIRTY, &cmd);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+#define test_cmd_set_dirty(hwpt_id, enabled) \
+ ASSERT_EQ(0, _test_cmd_set_dirty(self->fd, hwpt_id, enabled))
static int _test_cmd_create_access(int fd, unsigned int ioas_id,
__u32 *access_id, unsigned int flags)
{
Change mock_domain to supporting dirty tracking and add tests to exercise the new SET_DIRTY API in the mock_domain selftest fixture. Signed-off-by: Joao Martins <joao.m.martins@oracle.com> --- drivers/iommu/iommufd/selftest.c | 21 +++++++++++++++++++ tools/testing/selftests/iommu/iommufd.c | 15 +++++++++++++ tools/testing/selftests/iommu/iommufd_utils.h | 18 ++++++++++++++++ 3 files changed, 54 insertions(+)