Skip to content

Commit 18f8199

Browse files
nicolincjgunthorpe
authored andcommitted
iommufd/selftest: Prepare for mock_viommu_alloc_domain_nested()
A nested domain now can be allocated for a parent domain or for a vIOMMU object. Rework the existing allocators to prepare for the latter case. Link: https://patch.msgid.link/r/f62894ad8ccae28a8a616845947fe4b76135d79b.1730836219.git.nicolinc@nvidia.com Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Signed-off-by: Nicolin Chen <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent fd6b853 commit 18f8199

File tree

1 file changed

+50
-39
lines changed

1 file changed

+50
-39
lines changed

drivers/iommu/iommufd/selftest.c

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -318,55 +318,39 @@ static struct iommu_domain *mock_domain_alloc_paging(struct device *dev)
318318
return &mock->domain;
319319
}
320320

321-
static struct iommu_domain *
322-
__mock_domain_alloc_nested(struct mock_iommu_domain *mock_parent,
323-
const struct iommu_hwpt_selftest *user_cfg)
321+
static struct mock_iommu_domain_nested *
322+
__mock_domain_alloc_nested(const struct iommu_user_data *user_data)
324323
{
325324
struct mock_iommu_domain_nested *mock_nested;
326-
int i;
325+
struct iommu_hwpt_selftest user_cfg;
326+
int rc, i;
327+
328+
if (user_data->type != IOMMU_HWPT_DATA_SELFTEST)
329+
return ERR_PTR(-EOPNOTSUPP);
330+
331+
rc = iommu_copy_struct_from_user(&user_cfg, user_data,
332+
IOMMU_HWPT_DATA_SELFTEST, iotlb);
333+
if (rc)
334+
return ERR_PTR(rc);
327335

328336
mock_nested = kzalloc(sizeof(*mock_nested), GFP_KERNEL);
329337
if (!mock_nested)
330338
return ERR_PTR(-ENOMEM);
331-
mock_nested->parent = mock_parent;
332339
mock_nested->domain.ops = &domain_nested_ops;
333340
mock_nested->domain.type = IOMMU_DOMAIN_NESTED;
334341
for (i = 0; i < MOCK_NESTED_DOMAIN_IOTLB_NUM; i++)
335-
mock_nested->iotlb[i] = user_cfg->iotlb;
336-
return &mock_nested->domain;
342+
mock_nested->iotlb[i] = user_cfg.iotlb;
343+
return mock_nested;
337344
}
338345

339346
static struct iommu_domain *
340-
mock_domain_alloc_user(struct device *dev, u32 flags,
341-
struct iommu_domain *parent,
342-
const struct iommu_user_data *user_data)
347+
mock_domain_alloc_nested(struct iommu_domain *parent, u32 flags,
348+
const struct iommu_user_data *user_data)
343349
{
350+
struct mock_iommu_domain_nested *mock_nested;
344351
struct mock_iommu_domain *mock_parent;
345-
struct iommu_hwpt_selftest user_cfg;
346-
int rc;
347-
348-
/* must be mock_domain */
349-
if (!parent) {
350-
struct mock_dev *mdev = to_mock_dev(dev);
351-
bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
352-
bool no_dirty_ops = mdev->flags & MOCK_FLAGS_DEVICE_NO_DIRTY;
353-
struct iommu_domain *domain;
354-
355-
if (flags & (~(IOMMU_HWPT_ALLOC_NEST_PARENT |
356-
IOMMU_HWPT_ALLOC_DIRTY_TRACKING)))
357-
return ERR_PTR(-EOPNOTSUPP);
358-
if (user_data || (has_dirty_flag && no_dirty_ops))
359-
return ERR_PTR(-EOPNOTSUPP);
360-
domain = mock_domain_alloc_paging(dev);
361-
if (!domain)
362-
return ERR_PTR(-ENOMEM);
363-
if (has_dirty_flag)
364-
domain->dirty_ops = &dirty_ops;
365-
return domain;
366-
}
367352

368-
/* must be mock_domain_nested */
369-
if (user_data->type != IOMMU_HWPT_DATA_SELFTEST || flags)
353+
if (flags)
370354
return ERR_PTR(-EOPNOTSUPP);
371355
if (!parent || parent->ops != mock_ops.default_domain_ops)
372356
return ERR_PTR(-EINVAL);
@@ -375,12 +359,39 @@ mock_domain_alloc_user(struct device *dev, u32 flags,
375359
if (!mock_parent)
376360
return ERR_PTR(-EINVAL);
377361

378-
rc = iommu_copy_struct_from_user(&user_cfg, user_data,
379-
IOMMU_HWPT_DATA_SELFTEST, iotlb);
380-
if (rc)
381-
return ERR_PTR(rc);
362+
mock_nested = __mock_domain_alloc_nested(user_data);
363+
if (IS_ERR(mock_nested))
364+
return ERR_CAST(mock_nested);
365+
mock_nested->parent = mock_parent;
366+
return &mock_nested->domain;
367+
}
368+
369+
static struct iommu_domain *
370+
mock_domain_alloc_user(struct device *dev, u32 flags,
371+
struct iommu_domain *parent,
372+
const struct iommu_user_data *user_data)
373+
{
374+
bool has_dirty_flag = flags & IOMMU_HWPT_ALLOC_DIRTY_TRACKING;
375+
const u32 PAGING_FLAGS = IOMMU_HWPT_ALLOC_DIRTY_TRACKING |
376+
IOMMU_HWPT_ALLOC_NEST_PARENT;
377+
bool no_dirty_ops = to_mock_dev(dev)->flags &
378+
MOCK_FLAGS_DEVICE_NO_DIRTY;
379+
struct iommu_domain *domain;
380+
381+
if (parent)
382+
return mock_domain_alloc_nested(parent, flags, user_data);
382383

383-
return __mock_domain_alloc_nested(mock_parent, &user_cfg);
384+
if (user_data)
385+
return ERR_PTR(-EOPNOTSUPP);
386+
if ((flags & ~PAGING_FLAGS) || (has_dirty_flag && no_dirty_ops))
387+
return ERR_PTR(-EOPNOTSUPP);
388+
389+
domain = mock_domain_alloc_paging(dev);
390+
if (!domain)
391+
return ERR_PTR(-ENOMEM);
392+
if (has_dirty_flag)
393+
domain->dirty_ops = &dirty_ops;
394+
return domain;
384395
}
385396

386397
static void mock_domain_free(struct iommu_domain *domain)

0 commit comments

Comments
 (0)