Skip to content

Commit d93cf86

Browse files
yiliu1765joergroedel
authored andcommitted
iommu/vt-d: Consolidate the struct dev_pasid_info add/remove
The domain_add_dev_pasid() and domain_remove_dev_pasid() are added to consolidate the adding/removing of the struct dev_pasid_info. Besides, it includes the cache tag assign/unassign as well. This also prepares for adding domain replacement for pasid. The set_dev_pasid callbacks need to deal with the dev_pasid_info for both old and new domain. These two helpers make the life easier. intel_iommu_set_dev_pasid() and intel_svm_set_dev_pasid() are updated to use the helpers. Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Link: https://lore.kernel.org/r/20241107122234.7424-6-yi.l.liu@intel.com Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 7543ee6 commit d93cf86

File tree

3 files changed

+74
-51
lines changed

3 files changed

+74
-51
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4036,19 +4036,21 @@ static int intel_iommu_iotlb_sync_map(struct iommu_domain *domain,
40364036
return 0;
40374037
}
40384038

4039-
static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
4040-
struct iommu_domain *domain)
4039+
void domain_remove_dev_pasid(struct iommu_domain *domain,
4040+
struct device *dev, ioasid_t pasid)
40414041
{
40424042
struct device_domain_info *info = dev_iommu_priv_get(dev);
40434043
struct dev_pasid_info *curr, *dev_pasid = NULL;
40444044
struct intel_iommu *iommu = info->iommu;
40454045
struct dmar_domain *dmar_domain;
40464046
unsigned long flags;
40474047

4048-
if (domain->type == IOMMU_DOMAIN_IDENTITY) {
4049-
intel_pasid_tear_down_entry(iommu, dev, pasid, false);
4048+
if (!domain)
4049+
return;
4050+
4051+
/* Identity domain has no meta data for pasid. */
4052+
if (domain->type == IOMMU_DOMAIN_IDENTITY)
40504053
return;
4051-
}
40524054

40534055
dmar_domain = to_dmar_domain(domain);
40544056
spin_lock_irqsave(&dmar_domain->lock, flags);
@@ -4066,7 +4068,52 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
40664068
domain_detach_iommu(dmar_domain, iommu);
40674069
intel_iommu_debugfs_remove_dev_pasid(dev_pasid);
40684070
kfree(dev_pasid);
4069-
intel_pasid_tear_down_entry(iommu, dev, pasid, false);
4071+
}
4072+
4073+
static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
4074+
struct iommu_domain *domain)
4075+
{
4076+
struct device_domain_info *info = dev_iommu_priv_get(dev);
4077+
4078+
intel_pasid_tear_down_entry(info->iommu, dev, pasid, false);
4079+
domain_remove_dev_pasid(domain, dev, pasid);
4080+
}
4081+
4082+
struct dev_pasid_info *
4083+
domain_add_dev_pasid(struct iommu_domain *domain,
4084+
struct device *dev, ioasid_t pasid)
4085+
{
4086+
struct device_domain_info *info = dev_iommu_priv_get(dev);
4087+
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
4088+
struct intel_iommu *iommu = info->iommu;
4089+
struct dev_pasid_info *dev_pasid;
4090+
unsigned long flags;
4091+
int ret;
4092+
4093+
dev_pasid = kzalloc(sizeof(*dev_pasid), GFP_KERNEL);
4094+
if (!dev_pasid)
4095+
return ERR_PTR(-ENOMEM);
4096+
4097+
ret = domain_attach_iommu(dmar_domain, iommu);
4098+
if (ret)
4099+
goto out_free;
4100+
4101+
ret = cache_tag_assign_domain(dmar_domain, dev, pasid);
4102+
if (ret)
4103+
goto out_detach_iommu;
4104+
4105+
dev_pasid->dev = dev;
4106+
dev_pasid->pasid = pasid;
4107+
spin_lock_irqsave(&dmar_domain->lock, flags);
4108+
list_add(&dev_pasid->link_domain, &dmar_domain->dev_pasids);
4109+
spin_unlock_irqrestore(&dmar_domain->lock, flags);
4110+
4111+
return dev_pasid;
4112+
out_detach_iommu:
4113+
domain_detach_iommu(dmar_domain, iommu);
4114+
out_free:
4115+
kfree(dev_pasid);
4116+
return ERR_PTR(ret);
40704117
}
40714118

40724119
static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
@@ -4077,7 +4124,6 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
40774124
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
40784125
struct intel_iommu *iommu = info->iommu;
40794126
struct dev_pasid_info *dev_pasid;
4080-
unsigned long flags;
40814127
int ret;
40824128

40834129
if (!pasid_supported(iommu) || dev_is_real_dma_subdevice(dev))
@@ -4093,17 +4139,9 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
40934139
if (ret)
40944140
return ret;
40954141

4096-
dev_pasid = kzalloc(sizeof(*dev_pasid), GFP_KERNEL);
4097-
if (!dev_pasid)
4098-
return -ENOMEM;
4099-
4100-
ret = domain_attach_iommu(dmar_domain, iommu);
4101-
if (ret)
4102-
goto out_free;
4103-
4104-
ret = cache_tag_assign_domain(dmar_domain, dev, pasid);
4105-
if (ret)
4106-
goto out_detach_iommu;
4142+
dev_pasid = domain_add_dev_pasid(domain, dev, pasid);
4143+
if (IS_ERR(dev_pasid))
4144+
return PTR_ERR(dev_pasid);
41074145

41084146
if (dmar_domain->use_first_level)
41094147
ret = domain_setup_first_level(iommu, dmar_domain,
@@ -4112,24 +4150,17 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
41124150
ret = intel_pasid_setup_second_level(iommu, dmar_domain,
41134151
dev, pasid);
41144152
if (ret)
4115-
goto out_unassign_tag;
4153+
goto out_remove_dev_pasid;
41164154

4117-
dev_pasid->dev = dev;
4118-
dev_pasid->pasid = pasid;
4119-
spin_lock_irqsave(&dmar_domain->lock, flags);
4120-
list_add(&dev_pasid->link_domain, &dmar_domain->dev_pasids);
4121-
spin_unlock_irqrestore(&dmar_domain->lock, flags);
4155+
domain_remove_dev_pasid(old, dev, pasid);
41224156

41234157
if (domain->type & __IOMMU_DOMAIN_PAGING)
41244158
intel_iommu_debugfs_create_dev_pasid(dev_pasid);
41254159

41264160
return 0;
4127-
out_unassign_tag:
4128-
cache_tag_unassign_domain(dmar_domain, dev, pasid);
4129-
out_detach_iommu:
4130-
domain_detach_iommu(dmar_domain, iommu);
4131-
out_free:
4132-
kfree(dev_pasid);
4161+
4162+
out_remove_dev_pasid:
4163+
domain_remove_dev_pasid(domain, dev, pasid);
41334164
return ret;
41344165
}
41354166

drivers/iommu/intel/iommu.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,12 @@ void domain_detach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu);
12281228
void device_block_translation(struct device *dev);
12291229
int paging_domain_compatible(struct iommu_domain *domain, struct device *dev);
12301230

1231+
struct dev_pasid_info *
1232+
domain_add_dev_pasid(struct iommu_domain *domain,
1233+
struct device *dev, ioasid_t pasid);
1234+
void domain_remove_dev_pasid(struct iommu_domain *domain,
1235+
struct device *dev, ioasid_t pasid);
1236+
12311237
int dmar_ir_support(void);
12321238

12331239
void iommu_flush_write_buffer(struct intel_iommu *iommu);

drivers/iommu/intel/svm.c

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -115,43 +115,29 @@ static int intel_svm_set_dev_pasid(struct iommu_domain *domain,
115115
struct iommu_domain *old)
116116
{
117117
struct device_domain_info *info = dev_iommu_priv_get(dev);
118-
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
119118
struct intel_iommu *iommu = info->iommu;
120119
struct mm_struct *mm = domain->mm;
121120
struct dev_pasid_info *dev_pasid;
122121
unsigned long sflags;
123-
unsigned long flags;
124122
int ret = 0;
125123

126-
dev_pasid = kzalloc(sizeof(*dev_pasid), GFP_KERNEL);
127-
if (!dev_pasid)
128-
return -ENOMEM;
129-
130-
dev_pasid->dev = dev;
131-
dev_pasid->pasid = pasid;
132-
133-
ret = cache_tag_assign_domain(to_dmar_domain(domain), dev, pasid);
134-
if (ret)
135-
goto free_dev_pasid;
124+
dev_pasid = domain_add_dev_pasid(domain, dev, pasid);
125+
if (IS_ERR(dev_pasid))
126+
return PTR_ERR(dev_pasid);
136127

137128
/* Setup the pasid table: */
138129
sflags = cpu_feature_enabled(X86_FEATURE_LA57) ? PASID_FLAG_FL5LP : 0;
139130
ret = intel_pasid_setup_first_level(iommu, dev, mm->pgd, pasid,
140131
FLPT_DEFAULT_DID, sflags);
141132
if (ret)
142-
goto unassign_tag;
133+
goto out_remove_dev_pasid;
143134

144-
spin_lock_irqsave(&dmar_domain->lock, flags);
145-
list_add(&dev_pasid->link_domain, &dmar_domain->dev_pasids);
146-
spin_unlock_irqrestore(&dmar_domain->lock, flags);
135+
domain_remove_dev_pasid(old, dev, pasid);
147136

148137
return 0;
149138

150-
unassign_tag:
151-
cache_tag_unassign_domain(to_dmar_domain(domain), dev, pasid);
152-
free_dev_pasid:
153-
kfree(dev_pasid);
154-
139+
out_remove_dev_pasid:
140+
domain_remove_dev_pasid(domain, dev, pasid);
155141
return ret;
156142
}
157143

0 commit comments

Comments
 (0)