Skip to content

Commit d2f85a2

Browse files
yiliu1765joergroedel
authored andcommitted
iommu: Pass domain to remove_dev_pasid() op
Existing remove_dev_pasid() callbacks of the underlying iommu drivers get the attached domain from the group->pasid_array. However, the domain stored in group->pasid_array is not always correct in all scenarios. A wrong domain may result in failure in remove_dev_pasid() callback. To avoid such problems, it is more reliable to pass the domain to the remove_dev_pasid() op. Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Link: https://lore.kernel.org/r/20240328122958.83332-3-yi.l.liu@intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent b025dea commit d2f85a2

File tree

4 files changed

+12
-20
lines changed

4 files changed

+12
-20
lines changed

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3053,14 +3053,9 @@ static int arm_smmu_def_domain_type(struct device *dev)
30533053
return 0;
30543054
}
30553055

3056-
static void arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
3056+
static void arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
3057+
struct iommu_domain *domain)
30573058
{
3058-
struct iommu_domain *domain;
3059-
3060-
domain = iommu_get_domain_for_dev_pasid(dev, pasid, IOMMU_DOMAIN_SVA);
3061-
if (WARN_ON(IS_ERR(domain)) || !domain)
3062-
return;
3063-
30643059
arm_smmu_sva_remove_dev_pasid(domain, dev, pasid);
30653060
}
30663061

drivers/iommu/intel/iommu.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4587,19 +4587,15 @@ static int intel_iommu_iotlb_sync_map(struct iommu_domain *domain,
45874587
return 0;
45884588
}
45894589

4590-
static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
4590+
static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
4591+
struct iommu_domain *domain)
45914592
{
45924593
struct device_domain_info *info = dev_iommu_priv_get(dev);
4594+
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
45934595
struct dev_pasid_info *curr, *dev_pasid = NULL;
45944596
struct intel_iommu *iommu = info->iommu;
4595-
struct dmar_domain *dmar_domain;
4596-
struct iommu_domain *domain;
45974597
unsigned long flags;
45984598

4599-
domain = iommu_get_domain_for_dev_pasid(dev, pasid, 0);
4600-
if (WARN_ON_ONCE(!domain))
4601-
goto out_tear_down;
4602-
46034599
/*
46044600
* The SVA implementation needs to handle its own stuffs like the mm
46054601
* notification. Before consolidating that code into iommu core, let
@@ -4610,7 +4606,6 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
46104606
goto out_tear_down;
46114607
}
46124608

4613-
dmar_domain = to_dmar_domain(domain);
46144609
spin_lock_irqsave(&dmar_domain->lock, flags);
46154610
list_for_each_entry(curr, &dmar_domain->dev_pasids, link_domain) {
46164611
if (curr->dev == dev && curr->pasid == pasid) {

drivers/iommu/iommu.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3335,20 +3335,21 @@ static int __iommu_set_group_pasid(struct iommu_domain *domain,
33353335

33363336
if (device == last_gdev)
33373337
break;
3338-
ops->remove_dev_pasid(device->dev, pasid);
3338+
ops->remove_dev_pasid(device->dev, pasid, domain);
33393339
}
33403340
return ret;
33413341
}
33423342

33433343
static void __iommu_remove_group_pasid(struct iommu_group *group,
3344-
ioasid_t pasid)
3344+
ioasid_t pasid,
3345+
struct iommu_domain *domain)
33453346
{
33463347
struct group_device *device;
33473348
const struct iommu_ops *ops;
33483349

33493350
for_each_group_device(group, device) {
33503351
ops = dev_iommu_ops(device->dev);
3351-
ops->remove_dev_pasid(device->dev, pasid);
3352+
ops->remove_dev_pasid(device->dev, pasid, domain);
33523353
}
33533354
}
33543355

@@ -3418,7 +3419,7 @@ void iommu_detach_device_pasid(struct iommu_domain *domain, struct device *dev,
34183419
struct iommu_group *group = dev->iommu_group;
34193420

34203421
mutex_lock(&group->mutex);
3421-
__iommu_remove_group_pasid(group, pasid);
3422+
__iommu_remove_group_pasid(group, pasid, domain);
34223423
WARN_ON(xa_erase(&group->pasid_array, pasid) != domain);
34233424
mutex_unlock(&group->mutex);
34243425
}

include/linux/iommu.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,8 @@ struct iommu_ops {
578578
struct iommu_page_response *msg);
579579

580580
int (*def_domain_type)(struct device *dev);
581-
void (*remove_dev_pasid)(struct device *dev, ioasid_t pasid);
581+
void (*remove_dev_pasid)(struct device *dev, ioasid_t pasid,
582+
struct iommu_domain *domain);
582583

583584
const struct iommu_domain_ops *default_domain_ops;
584585
unsigned long pgsize_bitmap;

0 commit comments

Comments
 (0)