Skip to content

Commit 621838c

Browse files
LuBaolujoergroedel
authored andcommitted
iommu/vt-d: Refine intel_iommu_domain_alloc_user()
The domain_alloc_user ops should always allocate a guest-compatible page table unless specific allocation flags are specified. Currently, IOMMU_HWPT_ALLOC_NEST_PARENT and IOMMU_HWPT_ALLOC_DIRTY_TRACKING require special handling, as both require hardware support for scalable mode and second-stage translation. In such cases, the driver should select a second-stage page table for the paging domain. Suggested-by: Jason Gunthorpe <[email protected]> Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent ed56de8 commit 621838c

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,6 +3297,7 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
32973297
struct intel_iommu *iommu = info->iommu;
32983298
struct dmar_domain *dmar_domain;
32993299
struct iommu_domain *domain;
3300+
bool first_stage;
33003301

33013302
/* Must be NESTING domain */
33023303
if (parent) {
@@ -3313,8 +3314,20 @@ intel_iommu_domain_alloc_user(struct device *dev, u32 flags,
33133314
if (user_data || (dirty_tracking && !ssads_supported(iommu)))
33143315
return ERR_PTR(-EOPNOTSUPP);
33153316

3316-
/* Do not use first stage for user domain translation. */
3317-
dmar_domain = paging_domain_alloc(dev, false);
3317+
/*
3318+
* Always allocate the guest compatible page table unless
3319+
* IOMMU_HWPT_ALLOC_NEST_PARENT or IOMMU_HWPT_ALLOC_DIRTY_TRACKING
3320+
* is specified.
3321+
*/
3322+
if (nested_parent || dirty_tracking) {
3323+
if (!sm_supported(iommu) || !ecap_slts(iommu->ecap))
3324+
return ERR_PTR(-EOPNOTSUPP);
3325+
first_stage = false;
3326+
} else {
3327+
first_stage = first_level_by_default(iommu);
3328+
}
3329+
3330+
dmar_domain = paging_domain_alloc(dev, first_stage);
33183331
if (IS_ERR(dmar_domain))
33193332
return ERR_CAST(dmar_domain);
33203333
domain = &dmar_domain->domain;

0 commit comments

Comments
 (0)