
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. Introduce a new interface to avoid this. Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com> --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 18 ++++++++++-------- drivers/iommu/io-pgtable-arm.c | 3 ++- include/linux/io-pgtable.h | 7 +++++++ 3 files changed, 19 insertions(+), 9 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..9358d42b07c7 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2281,6 +2281,16 @@ static void arm_smmu_tlb_inv_range_domain(unsigned long iova, size_t size, arm_smmu_atc_inv_domain(smmu_domain, 0, iova, size); } +#ifdef CONFIG_HISILICON_ERRATUM_162100602 +void arm_smmu_tlb_flush_hisilicon_errata(void *cookie, unsigned long iova, size_t granule) +{ + struct arm_smmu_domain *smmu_domain = cookie; + + if (smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_BATCH) + arm_smmu_tlb_inv_range_domain(iova, granule, granule, true, cookie); +} +#endif + void arm_smmu_tlb_inv_range_asid(unsigned long iova, size_t size, int asid, size_t granule, bool leaf, struct arm_smmu_domain *smmu_domain) @@ -2310,14 +2320,6 @@ static void arm_smmu_tlb_inv_page_nosync(struct iommu_iotlb_gather *gather, 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) { - arm_smmu_tlb_inv_range_domain(iova, granule, granule, true, cookie); - return; - } -#endif arm_smmu_tlb_inv_range_domain(iova, size, granule, false, cookie); } diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index dc80f2661ff7..a2f11d9db262 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -366,7 +366,8 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, __arm_lpae_free_pages(cptep, tblsz, cfg); #ifdef CONFIG_HISILICON_ERRATUM_162100602 if (lvl <= 2) - io_pgtable_tlb_flush_walk(&data->iop, iova, 0, ARM_LPAE_GRANULE(data)); + arm_smmu_tlb_flush_hisilicon_errata(data->iop.cookie, + iova, ARM_LPAE_GRANULE(data)); #endif } else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) { __arm_lpae_sync_pte(ptep, cfg); diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 27b994e42ec4..03b574ef6d14 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -267,4 +267,11 @@ extern struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns; extern struct io_pgtable_init_fns io_pgtable_arm_v7s_init_fns; extern struct io_pgtable_init_fns io_pgtable_arm_mali_lpae_init_fns; +#ifdef CONFIG_HISILICON_ERRATUM_162100602 +void arm_smmu_tlb_flush_hisilicon_errata(void *cookie, unsigned long iova, size_t granule); +#else +static inline void arm_smmu_tlb_flush_hisilicon_errata(void *cookie, + unsigned long iova, size_t granule) {} +#endif + #endif /* __IO_PGTABLE_H */ -- 2.22.0