
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: 14554f1c8b05 ("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 | 5 ++++- drivers/iommu/io-pgtable-arm.c | 8 +++++--- include/linux/io-pgtable.h | 1 + 3 files changed, 10 insertions(+), 4 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 f778936d7579..46ab1c6b8785 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2508,7 +2508,7 @@ static void arm_smmu_tlb_inv_walk(unsigned long iova, size_t size, #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; } @@ -2730,6 +2730,9 @@ static int arm_smmu_domain_finalise(struct arm_smmu_domain *smmu_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 2822dc21c2c7..aecd5939e7b2 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -450,7 +450,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, __arm_lpae_free_pages(cptep, tblsz, cfg, data->iop.cookie); #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)) { @@ -1357,7 +1357,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) IO_PGTABLE_QUIRK_ARM_OUTER_WBWA | 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); @@ -1462,7 +1463,8 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie) if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_HD | IO_PGTABLE_QUIRK_ARM_BBML1 | IO_PGTABLE_QUIRK_ARM_BBML2 | - IO_PGTABLE_QUIRK_ARM_S2FWB)) + IO_PGTABLE_QUIRK_ARM_S2FWB | + 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 87950d35b996..24640a3151ea 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -105,6 +105,7 @@ struct io_pgtable_cfg { #define IO_PGTABLE_QUIRK_ARM_BBML1 BIT(8) #define IO_PGTABLE_QUIRK_ARM_BBML2 BIT(9) #define IO_PGTABLE_QUIRK_ARM_S2FWB BIT(10) + #define IO_PGTABLE_QUIRK_HISI_ERRATA BIT(11) unsigned long quirks; unsigned long pgsize_bitmap; unsigned int ias; -- 2.22.0