iommufd/selftest: Test IOMMU_HWPT_SET_DIRTY_TRACKING
authorJoao Martins <joao.m.martins@oracle.com>
Tue, 24 Oct 2023 13:51:06 +0000 (14:51 +0100)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 24 Oct 2023 14:58:44 +0000 (11:58 -0300)
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.

Link: https://lore.kernel.org/r/20231024135109.73787-16-joao.m.martins@oracle.com
Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/iommu/iommufd/selftest.c
tools/testing/selftests/iommu/iommufd.c
tools/testing/selftests/iommu/iommufd_utils.h

index 78362f2334f5fa852a3e0e789e6a284fdd9a6978..2773275566af3697e0c83a8d92a387ba5617c8a0 100644 (file)
@@ -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;
 }
 
index 6bebba183426e20c8f46683ff00870ad602960a3..8c46012006e1b0846256e4308419dc9ae46923b9 100644 (file)
@@ -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)
index 4ddafa29e638b8453a5ae7b6122a86f15c4e880d..e37af6291b226721ad698d0706d2b2d237027b6d 100644 (file)
@@ -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)
 {