Skip to content

Commit 115c0cc

Browse files
committed
Merge tag 'iommu-fixes-v6.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux
Pull iommu fixes from Joerg Roedel: - Per-domain device-list locking fixes for the AMD IOMMU driver - Fix incorrect use of smp_processor_id() in the NVidia-specific part of the ARM-SMMU-v3 driver - Intel IOMMU driver fixes: - Remove cache tags before disabling ATS - Avoid draining PRQ in sva mm release path - Fix qi_batch NULL pointer with nested parent domain * tag 'iommu-fixes-v6.13-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux: iommu/vt-d: Avoid draining PRQ in sva mm release path iommu/vt-d: Fix qi_batch NULL pointer with nested parent domain iommu/vt-d: Remove cache tags before disabling ATS iommu/amd: Add lockdep asserts for domain->dev_list iommu/amd: Put list_add/del(dev_data) back under the domain->lock iommu/tegra241-cmdqv: do not use smp_processor_id in preemptible context
2 parents 5d97859 + dda2b8c commit 115c0cc

File tree

5 files changed

+42
-11
lines changed

5 files changed

+42
-11
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,7 @@ static int domain_flush_pages_v2(struct protection_domain *pdom,
14151415
struct iommu_cmd cmd;
14161416
int ret = 0;
14171417

1418+
lockdep_assert_held(&pdom->lock);
14181419
list_for_each_entry(dev_data, &pdom->dev_list, list) {
14191420
struct amd_iommu *iommu = get_amd_iommu_from_dev(dev_data->dev);
14201421
u16 domid = dev_data->gcr3_info.domid;
@@ -1464,6 +1465,8 @@ static void __domain_flush_pages(struct protection_domain *domain,
14641465
ioasid_t pasid = IOMMU_NO_PASID;
14651466
bool gn = false;
14661467

1468+
lockdep_assert_held(&domain->lock);
1469+
14671470
if (pdom_is_v2_pgtbl_mode(domain)) {
14681471
gn = true;
14691472
ret = domain_flush_pages_v2(domain, address, size);
@@ -1585,6 +1588,8 @@ void amd_iommu_update_and_flush_device_table(struct protection_domain *domain)
15851588
{
15861589
struct iommu_dev_data *dev_data;
15871590

1591+
lockdep_assert_held(&domain->lock);
1592+
15881593
list_for_each_entry(dev_data, &domain->dev_list, list) {
15891594
struct amd_iommu *iommu = rlookup_amd_iommu(dev_data->dev);
15901595

@@ -2073,6 +2078,7 @@ static int attach_device(struct device *dev,
20732078
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
20742079
struct amd_iommu *iommu = get_amd_iommu_from_dev_data(dev_data);
20752080
struct pci_dev *pdev;
2081+
unsigned long flags;
20762082
int ret = 0;
20772083

20782084
mutex_lock(&dev_data->mutex);
@@ -2113,7 +2119,9 @@ static int attach_device(struct device *dev,
21132119

21142120
/* Update data structures */
21152121
dev_data->domain = domain;
2122+
spin_lock_irqsave(&domain->lock, flags);
21162123
list_add(&dev_data->list, &domain->dev_list);
2124+
spin_unlock_irqrestore(&domain->lock, flags);
21172125

21182126
/* Update device table */
21192127
dev_update_dte(dev_data, true);
@@ -2160,6 +2168,7 @@ static void detach_device(struct device *dev)
21602168
/* Flush IOTLB and wait for the flushes to finish */
21612169
spin_lock_irqsave(&domain->lock, flags);
21622170
amd_iommu_domain_flush_all(domain);
2171+
list_del(&dev_data->list);
21632172
spin_unlock_irqrestore(&domain->lock, flags);
21642173

21652174
/* Clear GCR3 table */
@@ -2168,7 +2177,6 @@ static void detach_device(struct device *dev)
21682177

21692178
/* Update data structures */
21702179
dev_data->domain = NULL;
2171-
list_del(&dev_data->list);
21722180

21732181
/* decrease reference counters - needs to happen after the flushes */
21742182
pdom_detach_iommu(iommu, domain);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ tegra241_cmdqv_get_cmdq(struct arm_smmu_device *smmu,
339339
* one CPU at a time can enter the process, while the others
340340
* will be spinning at the same lock.
341341
*/
342-
lidx = smp_processor_id() % cmdqv->num_lvcmdqs_per_vintf;
342+
lidx = raw_smp_processor_id() % cmdqv->num_lvcmdqs_per_vintf;
343343
vcmdq = vintf->lvcmdqs[lidx];
344344
if (!vcmdq || !READ_ONCE(vcmdq->enabled))
345345
return NULL;

drivers/iommu/intel/cache.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,35 @@ static void cache_tag_unassign(struct dmar_domain *domain, u16 did,
105105
spin_unlock_irqrestore(&domain->cache_lock, flags);
106106
}
107107

108+
/* domain->qi_batch will be freed in iommu_free_domain() path. */
109+
static int domain_qi_batch_alloc(struct dmar_domain *domain)
110+
{
111+
unsigned long flags;
112+
int ret = 0;
113+
114+
spin_lock_irqsave(&domain->cache_lock, flags);
115+
if (domain->qi_batch)
116+
goto out_unlock;
117+
118+
domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_ATOMIC);
119+
if (!domain->qi_batch)
120+
ret = -ENOMEM;
121+
out_unlock:
122+
spin_unlock_irqrestore(&domain->cache_lock, flags);
123+
124+
return ret;
125+
}
126+
108127
static int __cache_tag_assign_domain(struct dmar_domain *domain, u16 did,
109128
struct device *dev, ioasid_t pasid)
110129
{
111130
struct device_domain_info *info = dev_iommu_priv_get(dev);
112131
int ret;
113132

133+
ret = domain_qi_batch_alloc(domain);
134+
if (ret)
135+
return ret;
136+
114137
ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_IOTLB);
115138
if (ret || !info->ats_enabled)
116139
return ret;
@@ -139,6 +162,10 @@ static int __cache_tag_assign_parent_domain(struct dmar_domain *domain, u16 did,
139162
struct device_domain_info *info = dev_iommu_priv_get(dev);
140163
int ret;
141164

165+
ret = domain_qi_batch_alloc(domain);
166+
if (ret)
167+
return ret;
168+
142169
ret = cache_tag_assign(domain, did, dev, pasid, CACHE_TAG_NESTING_IOTLB);
143170
if (ret || !info->ats_enabled)
144171
return ret;
@@ -190,13 +217,6 @@ int cache_tag_assign_domain(struct dmar_domain *domain,
190217
u16 did = domain_get_id_for_dev(domain, dev);
191218
int ret;
192219

193-
/* domain->qi_bach will be freed in iommu_free_domain() path. */
194-
if (!domain->qi_batch) {
195-
domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_KERNEL);
196-
if (!domain->qi_batch)
197-
return -ENOMEM;
198-
}
199-
200220
ret = __cache_tag_assign_domain(domain, did, dev, pasid);
201221
if (ret || domain->domain.type != IOMMU_DOMAIN_NESTED)
202222
return ret;

drivers/iommu/intel/iommu.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3220,6 +3220,9 @@ void device_block_translation(struct device *dev)
32203220
struct intel_iommu *iommu = info->iommu;
32213221
unsigned long flags;
32223222

3223+
if (info->domain)
3224+
cache_tag_unassign_domain(info->domain, dev, IOMMU_NO_PASID);
3225+
32233226
iommu_disable_pci_caps(info);
32243227
if (!dev_is_real_dma_subdevice(dev)) {
32253228
if (sm_supported(iommu))
@@ -3236,7 +3239,6 @@ void device_block_translation(struct device *dev)
32363239
list_del(&info->link);
32373240
spin_unlock_irqrestore(&info->domain->lock, flags);
32383241

3239-
cache_tag_unassign_domain(info->domain, dev, IOMMU_NO_PASID);
32403242
domain_detach_iommu(info->domain, iommu);
32413243
info->domain = NULL;
32423244
}

drivers/iommu/intel/pasid.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
265265
iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
266266

267267
devtlb_invalidation_with_pasid(iommu, dev, pasid);
268-
intel_iommu_drain_pasid_prq(dev, pasid);
268+
if (!fault_ignore)
269+
intel_iommu_drain_pasid_prq(dev, pasid);
269270
}
270271

271272
/*

0 commit comments

Comments
 (0)