iommufd/selftest: Expand mock_domain with dev_flags
authorJoao Martins <joao.m.martins@oracle.com>
Tue, 24 Oct 2023 13:51:04 +0000 (14:51 +0100)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 24 Oct 2023 14:58:44 +0000 (11:58 -0300)
Expand mock_domain test to be able to manipulate the device capabilities.
This allows testing with mockdev without dirty tracking support advertised
and thus make sure enforce_dirty test does the expected.

To avoid breaking IOMMUFD_TEST UABI replicate the mock_domain struct and
thus add an input dev_flags at the end.

Link: https://lore.kernel.org/r/20231024135109.73787-14-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/iommufd_test.h
drivers/iommu/iommufd/selftest.c
tools/testing/selftests/iommu/iommufd_utils.h

index 3f3644375bf13c8fa78600f1f9e15d893195af65..9817edcd89683978e824d01a90ef9d6f0f98b483 100644 (file)
@@ -19,6 +19,7 @@ enum {
        IOMMU_TEST_OP_SET_TEMP_MEMORY_LIMIT,
        IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE,
        IOMMU_TEST_OP_ACCESS_REPLACE_IOAS,
+       IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS,
 };
 
 enum {
@@ -40,6 +41,10 @@ enum {
        MOCK_FLAGS_ACCESS_CREATE_NEEDS_PIN_PAGES = 1 << 0,
 };
 
+enum {
+       MOCK_FLAGS_DEVICE_NO_DIRTY = 1 << 0,
+};
+
 struct iommu_test_cmd {
        __u32 size;
        __u32 op;
@@ -56,6 +61,13 @@ struct iommu_test_cmd {
                        /* out_idev_id is the standard iommufd_bind object */
                        __u32 out_idev_id;
                } mock_domain;
+               struct {
+                       __u32 out_stdev_id;
+                       __u32 out_hwpt_id;
+                       __u32 out_idev_id;
+                       /* Expand mock_domain to set mock device flags */
+                       __u32 dev_flags;
+               } mock_domain_flags;
                struct {
                        __u32 pt_id;
                } mock_domain_replace;
index fe7e3c7d933a41142dbe88b7bdcef0e9b6546fb2..bd3704b28bfba401dffe767b6631aee11cf046b5 100644 (file)
@@ -96,6 +96,7 @@ enum selftest_obj_type {
 
 struct mock_dev {
        struct device dev;
+       unsigned long flags;
 };
 
 struct selftest_obj {
@@ -381,7 +382,7 @@ static void mock_dev_release(struct device *dev)
        kfree(mdev);
 }
 
-static struct mock_dev *mock_dev_create(void)
+static struct mock_dev *mock_dev_create(unsigned long dev_flags)
 {
        struct mock_dev *mdev;
        int rc;
@@ -391,6 +392,7 @@ static struct mock_dev *mock_dev_create(void)
                return ERR_PTR(-ENOMEM);
 
        device_initialize(&mdev->dev);
+       mdev->flags = dev_flags;
        mdev->dev.release = mock_dev_release;
        mdev->dev.bus = &iommufd_mock_bus_type.bus;
 
@@ -426,6 +428,7 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
        struct iommufd_device *idev;
        struct selftest_obj *sobj;
        u32 pt_id = cmd->id;
+       u32 dev_flags = 0;
        u32 idev_id;
        int rc;
 
@@ -436,7 +439,10 @@ static int iommufd_test_mock_domain(struct iommufd_ucmd *ucmd,
        sobj->idev.ictx = ucmd->ictx;
        sobj->type = TYPE_IDEV;
 
-       sobj->idev.mock_dev = mock_dev_create();
+       if (cmd->op == IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS)
+               dev_flags = cmd->mock_domain_flags.dev_flags;
+
+       sobj->idev.mock_dev = mock_dev_create(dev_flags);
        if (IS_ERR(sobj->idev.mock_dev)) {
                rc = PTR_ERR(sobj->idev.mock_dev);
                goto out_sobj;
@@ -1019,6 +1025,7 @@ int iommufd_test(struct iommufd_ucmd *ucmd)
                                                 cmd->add_reserved.start,
                                                 cmd->add_reserved.length);
        case IOMMU_TEST_OP_MOCK_DOMAIN:
+       case IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS:
                return iommufd_test_mock_domain(ucmd, cmd);
        case IOMMU_TEST_OP_MOCK_DOMAIN_REPLACE:
                return iommufd_test_mock_domain_replace(
index be4970a849776f3b9baadbcea7bb19e7aa517616..1e0736adc9912b529a918b042a8d53dca785bb0d 100644 (file)
@@ -74,6 +74,35 @@ static int _test_cmd_mock_domain(int fd, unsigned int ioas_id, __u32 *stdev_id,
        EXPECT_ERRNO(_errno, _test_cmd_mock_domain(self->fd, ioas_id, \
                                                   stdev_id, hwpt_id, NULL))
 
+static int _test_cmd_mock_domain_flags(int fd, unsigned int ioas_id,
+                                      __u32 stdev_flags, __u32 *stdev_id,
+                                      __u32 *hwpt_id, __u32 *idev_id)
+{
+       struct iommu_test_cmd cmd = {
+               .size = sizeof(cmd),
+               .op = IOMMU_TEST_OP_MOCK_DOMAIN_FLAGS,
+               .id = ioas_id,
+               .mock_domain_flags = { .dev_flags = stdev_flags },
+       };
+       int ret;
+
+       ret = ioctl(fd, IOMMU_TEST_CMD, &cmd);
+       if (ret)
+               return ret;
+       if (stdev_id)
+               *stdev_id = cmd.mock_domain_flags.out_stdev_id;
+       assert(cmd.id != 0);
+       if (hwpt_id)
+               *hwpt_id = cmd.mock_domain_flags.out_hwpt_id;
+       if (idev_id)
+               *idev_id = cmd.mock_domain_flags.out_idev_id;
+       return 0;
+}
+#define test_err_mock_domain_flags(_errno, ioas_id, flags, stdev_id, hwpt_id) \
+       EXPECT_ERRNO(_errno,                                                  \
+                    _test_cmd_mock_domain_flags(self->fd, ioas_id, flags,    \
+                                                stdev_id, hwpt_id, NULL))
+
 static int _test_cmd_mock_domain_replace(int fd, __u32 stdev_id, __u32 pt_id,
                                         __u32 *hwpt_id)
 {