Skip to content

Commit 51d113c

Browse files
jpbruckerwilldeacon
authored andcommitted
iommu/arm-smmu-v3: Make BTM optional for SVA
When BTM isn't supported by the SMMU, send invalidations on the command queue. Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Jean-Philippe Brucker <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent eba8d2f commit 51d113c

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,13 @@ static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn,
182182
unsigned long start, unsigned long end)
183183
{
184184
struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn);
185+
struct arm_smmu_domain *smmu_domain = smmu_mn->domain;
186+
size_t size = end - start + 1;
185187

186-
arm_smmu_atc_inv_domain(smmu_mn->domain, mm->pasid, start,
187-
end - start + 1);
188+
if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM))
189+
arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid,
190+
PAGE_SIZE, false, smmu_domain);
191+
arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, start, size);
188192
}
189193

190194
static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
@@ -391,7 +395,7 @@ bool arm_smmu_sva_supported(struct arm_smmu_device *smmu)
391395
unsigned long reg, fld;
392396
unsigned long oas;
393397
unsigned long asid_bits;
394-
u32 feat_mask = ARM_SMMU_FEAT_BTM | ARM_SMMU_FEAT_COHERENCY;
398+
u32 feat_mask = ARM_SMMU_FEAT_COHERENCY;
395399

396400
if (vabits_actual == 52)
397401
feat_mask |= ARM_SMMU_FEAT_VAX;

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,21 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size,
17431743
arm_smmu_atc_inv_domain(smmu_domain, 0, iova, size);
17441744
}
17451745

1746+
void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
1747+
size_t granule, bool leaf,
1748+
struct arm_smmu_domain *smmu_domain)
1749+
{
1750+
struct arm_smmu_cmdq_ent cmd = {
1751+
.opcode = CMDQ_OP_TLBI_NH_VA,
1752+
.tlbi = {
1753+
.asid = asid,
1754+
.leaf = leaf,
1755+
},
1756+
};
1757+
1758+
__arm_smmu_tlb_inv_range(&cmd, iova, size, granule, smmu_domain);
1759+
}
1760+
17461761
static void arm_smmu_tlb_inv_page_nosync(struct iommu_iotlb_gather *gather,
17471762
unsigned long iova, size_t granule,
17481763
void *cookie)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,9 @@ extern struct arm_smmu_ctx_desc quiet_cd;
694694
int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain, int ssid,
695695
struct arm_smmu_ctx_desc *cd);
696696
void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);
697+
void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid,
698+
size_t granule, bool leaf,
699+
struct arm_smmu_domain *smmu_domain);
697700
bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd);
698701
int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain, int ssid,
699702
unsigned long iova, size_t size);

0 commit comments

Comments
 (0)