Skip to content

Commit 8f1b460

Browse files
committed
Merge tag 'iommu-fixes-v6.6-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu
Pull iommu fixes from Joerg Roedel: - Arm SMMU fixes from Will Deacon: - Fix TLB range command encoding when TTL, Num and Scale are all zero - Fix soft lockup by limiting TLB invalidation ops issued by SVA - Fix clocks description for SDM630 platform in arm-smmu DT binding - Intel VT-d fix from Lu Baolu: - Fix a suspend/hibernation problem in iommu_suspend() - Mediatek driver: Fix page table sharing for addresses over 4GiB - Apple/Dart: DMA_FQ handling fix in attach_dev() * tag 'iommu-fixes-v6.6-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: iommu/vt-d: Avoid memory allocation in iommu_suspend() iommu/apple-dart: Handle DMA_FQ domains in attach_dev() iommu/mediatek: Fix share pgtable for iova over 4GB iommu/arm-smmu-v3: Fix soft lockup triggered by arm_smmu_mm_invalidate_range dt-bindings: arm-smmu: Fix SDM630 clocks description iommu/arm-smmu-v3: Avoid constructing invalid range commands
2 parents 8a749fd + 59df44b commit 8f1b460

File tree

7 files changed

+33
-32
lines changed

7 files changed

+33
-32
lines changed

Documentation/devicetree/bindings/iommu/arm,smmu.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ allOf:
270270
contains:
271271
enum:
272272
- qcom,msm8998-smmu-v2
273+
- qcom,sdm630-smmu-v2
273274
then:
274275
anyOf:
275276
- properties:
@@ -311,7 +312,6 @@ allOf:
311312
compatible:
312313
contains:
313314
enum:
314-
- qcom,sdm630-smmu-v2
315315
- qcom,sm6375-smmu-v2
316316
then:
317317
anyOf:

drivers/iommu/apple-dart.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,7 @@ static int apple_dart_attach_dev(struct iommu_domain *domain,
671671
return ret;
672672

673673
switch (domain->type) {
674-
case IOMMU_DOMAIN_DMA:
675-
case IOMMU_DOMAIN_UNMANAGED:
674+
default:
676675
ret = apple_dart_domain_add_streams(dart_domain, cfg);
677676
if (ret)
678677
return ret;

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ static void arm_smmu_free_shared_cd(struct arm_smmu_ctx_desc *cd)
186186
}
187187
}
188188

189+
/*
190+
* Cloned from the MAX_TLBI_OPS in arch/arm64/include/asm/tlbflush.h, this
191+
* is used as a threshold to replace per-page TLBI commands to issue in the
192+
* command queue with an address-space TLBI command, when SMMU w/o a range
193+
* invalidation feature handles too many per-page TLBI commands, which will
194+
* otherwise result in a soft lockup.
195+
*/
196+
#define CMDQ_MAX_TLBI_OPS (1 << (PAGE_SHIFT - 3))
197+
189198
static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn,
190199
struct mm_struct *mm,
191200
unsigned long start,
@@ -201,8 +210,13 @@ static void arm_smmu_mm_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn,
201210
* range. So do a simple translation here by calculating size correctly.
202211
*/
203212
size = end - start;
204-
if (size == ULONG_MAX)
205-
size = 0;
213+
if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_RANGE_INV)) {
214+
if (size >= CMDQ_MAX_TLBI_OPS * PAGE_SIZE)
215+
size = 0;
216+
} else {
217+
if (size == ULONG_MAX)
218+
size = 0;
219+
}
206220

207221
if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) {
208222
if (!size)

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,18 +1895,23 @@ static void __arm_smmu_tlb_inv_range(struct arm_smmu_cmdq_ent *cmd,
18951895
/* Get the leaf page size */
18961896
tg = __ffs(smmu_domain->domain.pgsize_bitmap);
18971897

1898+
num_pages = size >> tg;
1899+
18981900
/* Convert page size of 12,14,16 (log2) to 1,2,3 */
18991901
cmd->tlbi.tg = (tg - 10) / 2;
19001902

19011903
/*
1902-
* Determine what level the granule is at. For non-leaf, io-pgtable
1903-
* assumes .tlb_flush_walk can invalidate multiple levels at once,
1904-
* so ignore the nominal last-level granule and leave TTL=0.
1904+
* Determine what level the granule is at. For non-leaf, both
1905+
* io-pgtable and SVA pass a nominal last-level granule because
1906+
* they don't know what level(s) actually apply, so ignore that
1907+
* and leave TTL=0. However for various errata reasons we still
1908+
* want to use a range command, so avoid the SVA corner case
1909+
* where both scale and num could be 0 as well.
19051910
*/
19061911
if (cmd->tlbi.leaf)
19071912
cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3));
1908-
1909-
num_pages = size >> tg;
1913+
else if ((num_pages & CMDQ_TLBI_RANGE_NUM_MAX) == 1)
1914+
num_pages++;
19101915
}
19111916

19121917
cmds.num = 0;

drivers/iommu/intel/iommu.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2998,13 +2998,6 @@ static int iommu_suspend(void)
29982998
struct intel_iommu *iommu = NULL;
29992999
unsigned long flag;
30003000

3001-
for_each_active_iommu(iommu, drhd) {
3002-
iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32),
3003-
GFP_KERNEL);
3004-
if (!iommu->iommu_state)
3005-
goto nomem;
3006-
}
3007-
30083001
iommu_flush_all();
30093002

30103003
for_each_active_iommu(iommu, drhd) {
@@ -3024,12 +3017,6 @@ static int iommu_suspend(void)
30243017
raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
30253018
}
30263019
return 0;
3027-
3028-
nomem:
3029-
for_each_active_iommu(iommu, drhd)
3030-
kfree(iommu->iommu_state);
3031-
3032-
return -ENOMEM;
30333020
}
30343021

30353022
static void iommu_resume(void)
@@ -3061,9 +3048,6 @@ static void iommu_resume(void)
30613048

30623049
raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
30633050
}
3064-
3065-
for_each_active_iommu(iommu, drhd)
3066-
kfree(iommu->iommu_state);
30673051
}
30683052

30693053
static struct syscore_ops iommu_syscore_ops = {

drivers/iommu/intel/iommu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ struct intel_iommu {
681681
struct iopf_queue *iopf_queue;
682682
unsigned char iopfq_name[16];
683683
struct q_inval *qi; /* Queued invalidation info */
684-
u32 *iommu_state; /* Store iommu states between suspend and resume.*/
684+
u32 iommu_state[MAX_SR_DMAR_REGS]; /* Store iommu states between suspend and resume.*/
685685

686686
#ifdef CONFIG_IRQ_REMAP
687687
struct ir_table *ir_table; /* Interrupt remapping info */

drivers/iommu/mtk_iommu.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ struct mtk_iommu_data {
262262
struct device *smicomm_dev;
263263

264264
struct mtk_iommu_bank_data *bank;
265-
struct mtk_iommu_domain *share_dom; /* For 2 HWs share pgtable */
265+
struct mtk_iommu_domain *share_dom;
266266

267267
struct regmap *pericfg;
268268
struct mutex mutex; /* Protect m4u_group/m4u_dom above */
@@ -643,8 +643,8 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
643643
struct mtk_iommu_domain *share_dom = data->share_dom;
644644
const struct mtk_iommu_iova_region *region;
645645

646-
/* Always use share domain in sharing pgtable case */
647-
if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE) && share_dom) {
646+
/* Share pgtable when 2 MM IOMMU share the pgtable or one IOMMU use multiple iova ranges */
647+
if (share_dom) {
648648
dom->iop = share_dom->iop;
649649
dom->cfg = share_dom->cfg;
650650
dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap;
@@ -677,8 +677,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
677677
/* Update our support page sizes bitmap */
678678
dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap;
679679

680-
if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE))
681-
data->share_dom = dom;
680+
data->share_dom = dom;
682681

683682
update_iova_region:
684683
/* Update the iova region for this domain */

0 commit comments

Comments
 (0)