Skip to content

Commit 7accef5

Browse files
committed
Merge tag 'arm-smmu-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into iommu/fixes
Arm SMMU fixes for 6.6 -rc - 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
2 parents b07eba7 + d5afb4b commit 7accef5

File tree

3 files changed

+27
-8
lines changed

3 files changed

+27
-8
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/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;

0 commit comments

Comments
 (0)