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 dee6ca2fbdb151d4ac2b92d2993425bc07246276..a79662dfbebb499a9310af018921353e670d41f2 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2506,9 +2506,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; } @@ -2730,6 +2728,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; @@ -5035,13 +5036,6 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu) } break; } - -#ifdef CONFIG_HISILICON_ERRATUM_162100602 - reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR); - if (FIELD_GET(IIDR_VARIANT, reg) == 0x3 && - FIELD_GET(IIDR_REVISION, reg) == 0x2) - smmu->options |= ARM_SMMU_OPT_SYNC_MAP; -#endif } #ifdef CONFIG_HISILICON_ERRATUM_162100602 @@ -5052,8 +5046,6 @@ static void hisi_smmu_check_errata(struct arm_smmu_device *smmu) if (!(smmu->options & ARM_SMMU_OPT_SYNC_MAP)) return; - smmu->options |= ARM_SMMU_OPT_SYNC_MAP; - reg = readl_relaxed(smmu->base + ARM_SMMU_USER_CFG1); reg = reg & GENMASK(15, 0); for (i = 0; i < 8; i++) { diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 2822dc21c2c793d436cefcf60bd721a862a10c47..aecd5939e7b25c1aa29464735be1904087346c6c 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 87950d35b99636177cec6f76841a9275b2b8858b..24640a3151eabea79ae6bd04232037c5fd4fa01e 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;