
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IBZUQU ------------------------------------------- The tlb invalidation code for smmu pagetable prefetch problem might cause a extra tlb invalidation for atc. Prevent it from happening. Fixes: 2da3f6871b6e ("iommu/arm-smmu-v3: Reducing the CMD_SYNC times") Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 7 ++++--- drivers/iommu/io-pgtable-arm.c | 8 +++++--- include/linux/io-pgtable.h | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index cedc1eda7250..090ccda84b46 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2311,9 +2311,7 @@ static void arm_smmu_tlb_inv_walk(unsigned long iova, size_t size, size_t granule, void *cookie) { #ifdef CONFIG_HISILICON_ERRATUM_162100602 - struct arm_smmu_domain *smmu_domain = cookie; - - if (!size && smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_BATCH) { + if (!size) { arm_smmu_tlb_inv_range_domain(iova, granule, granule, true, cookie); return; } @@ -2584,6 +2582,9 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain, else if (smmu->features & ARM_SMMU_FEAT_BBML2) pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_ARM_BBML2; + if (smmu->options & ARM_SMMU_OPT_SYNC_BATCH) + pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_HISI_ERRATA; + pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain); if (!pgtbl_ops) return -ENOMEM; diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index dc80f2661ff7..a4e75f0e4c23 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -365,7 +365,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, if (pte) __arm_lpae_free_pages(cptep, tblsz, cfg); #ifdef CONFIG_HISILICON_ERRATUM_162100602 - if (lvl <= 2) + if (lvl <= 2 && (cfg->quirks & IO_PGTABLE_QUIRK_HISI_ERRATA)) io_pgtable_tlb_flush_walk(&data->iop, iova, 0, ARM_LPAE_GRANULE(data)); #endif } else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) { @@ -1163,7 +1163,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) IO_PGTABLE_QUIRK_ARM_TTBR1 | IO_PGTABLE_QUIRK_ARM_HD | IO_PGTABLE_QUIRK_ARM_BBML1 | - IO_PGTABLE_QUIRK_ARM_BBML2)) + IO_PGTABLE_QUIRK_ARM_BBML2 | + IO_PGTABLE_QUIRK_HISI_ERRATA)) return NULL; data = arm_lpae_alloc_pgtable(cfg); @@ -1263,7 +1264,8 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie) if (cfg->quirks & ~(IO_PGTABLE_QUIRK_NON_STRICT | IO_PGTABLE_QUIRK_ARM_HD | IO_PGTABLE_QUIRK_ARM_BBML1 | - IO_PGTABLE_QUIRK_ARM_BBML2)) + IO_PGTABLE_QUIRK_ARM_BBML2 | + IO_PGTABLE_QUIRK_HISI_ERRATA)) return NULL; data = arm_lpae_alloc_pgtable(cfg); diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 27b994e42ec4..7fc863011474 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -100,6 +100,7 @@ struct io_pgtable_cfg { #define IO_PGTABLE_QUIRK_ARM_HD BIT(6) #define IO_PGTABLE_QUIRK_ARM_BBML1 BIT(7) #define IO_PGTABLE_QUIRK_ARM_BBML2 BIT(8) + #define IO_PGTABLE_QUIRK_HISI_ERRATA BIT(9) unsigned long quirks; unsigned long pgsize_bitmap; unsigned int ias; -- 2.22.0