aboutsummaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorJoao Martins2023-10-24 14:51:05 +0100
committerJason Gunthorpe2023-10-24 11:58:44 -0300
commit266ce58989ba05e2a24460fdbf402d766c2e3870 (patch)
tree306f83d46769f067ff1962e07ee46df8a2a55530 /drivers/iommu
parente04b23c8d4ed977dbab4a4159f9e4d9a878b5c65 (diff)
iommufd/selftest: Test IOMMU_HWPT_ALLOC_DIRTY_TRACKING
In order to selftest the iommu domain dirty enforcing implement the mock_domain necessary support and add a new dev_flags to test that the hwpt_alloc/attach_device fails as expected. Expand the existing mock_domain fixture with a enforce_dirty test that exercises the hwpt_alloc and device attachment. Link: https://lore.kernel.org/r/20231024135109.73787-15-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>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/iommufd/selftest.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c
index bd3704b28bfb..78362f2334f5 100644
--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -119,6 +119,11 @@ static void mock_domain_blocking_free(struct iommu_domain *domain)
static int mock_domain_nop_attach(struct iommu_domain *domain,
struct device *dev)
{
+ struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);
+
+ if (domain->dirty_ops && (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
+ return -EINVAL;
+
return 0;
}
@@ -147,6 +152,25 @@ static void *mock_domain_hw_info(struct device *dev, u32 *length, u32 *type)
return info;
}
+static int mock_domain_set_dirty_tracking(struct iommu_domain *domain,
+ bool enable)
+{
+ return 0;
+}
+
+static int mock_domain_read_and_clear_dirty(struct iommu_domain *domain,
+ unsigned long iova, size_t size,
+ unsigned long flags,
+ struct iommu_dirty_bitmap *dirty)
+{
+ return 0;
+}
+
+const struct iommu_dirty_ops dirty_ops = {
+ .set_dirty_tracking = mock_domain_set_dirty_tracking,
+ .read_and_clear_dirty = mock_domain_read_and_clear_dirty,
+};
+
static const struct iommu_ops mock_ops;
static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
@@ -174,12 +198,20 @@ static struct iommu_domain *mock_domain_alloc(unsigned int iommu_domain_type)
static struct iommu_domain *
mock_domain_alloc_user(struct device *dev, u32 flags)
{
+ struct mock_dev *mdev = container_of(dev, struct mock_dev, dev);
struct iommu_domain *domain;
- if (flags & (~IOMMU_HWPT_ALLOC_NEST_PARENT))
+ if (flags &
+ (~(IOMMU_HWPT_ALLOC_NEST_PARENT | IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ if ((flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING) &&
+ (mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
return ERR_PTR(-EOPNOTSUPP);
domain = mock_domain_alloc(IOMMU_DOMAIN_UNMANAGED);
+ if (domain && !(mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY))
+ domain->dirty_ops = &dirty_ops;
if (!domain)
domain = ERR_PTR(-ENOMEM);
return domain;
@@ -387,6 +419,9 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags)
struct mock_dev *mdev;
int rc;
+ if (dev_flags & ~(MOCK_FLAGS_DEVICE_NO_DIRTY))
+ return ERR_PTR(-EINVAL);
+
mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev)
return ERR_PTR(-ENOMEM);