diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index 30d3091452f959a5161bafa27eb816f3e81632cd..2b6208e0b42123a1ad730a8d30cb6fb7fb5d492a 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -207,6 +207,7 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | LINXICORE9100 | #1980005 | HISILICON_ERRATUM_1980005 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | SMMUv3 | #162100602 | HISILICON_ERRATUM_162100602 | +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index e3821be64a22fed210fae39b68b6e4c720918621..67bc2ad13453c1fcbe2ed2837249bcc62388bae1 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1187,14 +1187,13 @@ config HISILICON_ERRATUM_1980005 config HISILICON_ERRATUM_162100602 bool "Hisilicon erratum 162100602" - depends on ARM_SMMU_V3 + depends on ARM_SMMU_V3 && ARCH_HISI default y help - On Hisilicon LINXICORE9100 cores, SMMU pagetable prefetch features may - prefetch and use a invalid PTE even the PTE is valid at that time. This - will cause the device trigger fake pagefaults. If the SMMU works in - terminate mode, transactions which occur fake pagefaults will be aborted, - and could result in unexpected errors. + SMMU pagetable prefetch features may prefetch and use a invalid PTE even + the PTE is valid at that time. This will cause the device trigger fake + pagefaults. If the SMMU works in terminate mode, transactions which occur + fake pagefaults will be aborted, and could result in unexpected errors. If unsure, say Y. diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index c569e6c0ac07f274410991b2d3760e2709e61997..a686a96d966aa652d70c834b8fd8259b7478403f 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -360,13 +360,6 @@ static const struct midr_range hisilicon_erratum_162100125_cpus[] = { }; #endif -#ifdef CONFIG_HISILICON_ERRATUM_162100602 -static const struct midr_range hisilicon_erratum_162100602_cpus[] = { - MIDR_REV(MIDR_HISI_LINXICORE9100, 0, 0), - {}, -}; -#endif - #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003 static const struct arm64_cpu_capabilities qcom_erratum_1003_list[] = { { @@ -598,13 +591,6 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ERRATA_MIDR_RANGE_LIST(hisilicon_erratum_162100125_cpus), }, #endif -#ifdef CONFIG_HISILICON_ERRATUM_162100602 - { - .desc = "Hisilicon erratum 162100602", - .capability = ARM64_WORKAROUND_HISILICON_ERRATUM_162100602, - ERRATA_MIDR_RANGE_LIST(hisilicon_erratum_162100602_cpus), - }, -#endif #ifdef CONFIG_HISILICON_ERRATUM_1980005 { .desc = "Hisilicon erratum 1980005 (IDC)", diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 8c4f338e6568262e91efdc9a1a849bddd9bcc4aa..94c85ead16e2ce9566b71663928a0a034d15246a 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -105,7 +105,6 @@ WORKAROUND_SPECULATIVE_AT WORKAROUND_HISILICON_ERRATUM_162100125 WORKAROUND_HISI_HIP08_RU_PREFETCH WORKAROUND_HISILICON_1980005 -WORKAROUND_HISILICON_ERRATUM_162100602 KABI_RESERVE_1 KABI_RESERVE_2 KABI_RESERVE_3 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 de95468a129342af8224d3976f6a0ba9486ff91f..09dc2d690de13eb1586824cb3f367780ceadbabc 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2778,12 +2778,12 @@ static void arm_smmu_iotlb_sync(struct iommu_domain *domain, #ifdef CONFIG_HISILICON_ERRATUM_162100602 static void arm_smmu_iotlb_sync_map(struct iommu_domain *domain, - unsigned long iova, size_t size) + unsigned long iova, size_t size) { struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); size_t granule_size; - if (!cpus_have_const_cap(ARM64_WORKAROUND_HISILICON_ERRATUM_162100602)) + if (!(smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_MAP)) return; granule_size = 1 << __ffs(smmu_domain->domain.pgsize_bitmap); @@ -3357,7 +3357,7 @@ static struct iommu_ops arm_smmu_ops = { .flush_iotlb_all = arm_smmu_flush_iotlb_all, .iotlb_sync = arm_smmu_iotlb_sync, #ifdef CONFIG_HISILICON_ERRATUM_162100602 - .iotlb_sync_map = arm_smmu_iotlb_sync_map, + .iotlb_sync_map = arm_smmu_iotlb_sync_map, #endif .iova_to_phys = arm_smmu_iova_to_phys, .enable_nesting = arm_smmu_enable_nesting, @@ -4247,6 +4247,13 @@ 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 } static void arm_smmu_get_httu(struct arm_smmu_device *smmu, u32 reg) diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index a6381d33647c76e5e0f7d0705a4451f082829d98..f04d10223f6ee2998a83f8c0e6c052986f13cb6e 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -704,6 +704,7 @@ struct arm_smmu_device { #define ARM_SMMU_OPT_PAGE0_REGS_ONLY (1 << 1) #define ARM_SMMU_OPT_MSIPOLL (1 << 2) #define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3) +#define ARM_SMMU_OPT_SYNC_MAP (1 << 4) u32 options; #ifdef CONFIG_ARM_SMMU_V3_ECMDQ