hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8MVBZ CVE: NA
-----------------------------------------------
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.
To fix this problem, we need to add a SYNC command after smmu has map a iova, then smmu will always try to get the newest PTE.
Signed-off-by: Zhang Zekun zhangzekun11@huawei.com --- v2: - add a config to explictly set erratum config, no code logic change
Documentation/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 13 +++++++++++++ arch/arm64/configs/openeuler_defconfig | 1 + arch/arm64/include/asm/cpucaps.h | 1 + arch/arm64/kernel/cpu_errata.c | 14 ++++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 20 ++++++++++++++++++++ 6 files changed, 51 insertions(+)
diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index a9441bfebb0d..1f06e18a1859 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -156,6 +156,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | LINXICORE9100 | #162100125 | HISILICON_ERRATUM_162100125 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | LINXICORE9100 | #162100602 | HISILICON_ERRATUM_162100602 | ++----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | HIP09 | #162102203 | HISILICON_ERRATUM_162102203 | +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c5eca65c27fc..851d24a35e4e 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -836,6 +836,19 @@ config HISILICON_ERRATUM_162102203
If unsure, say N.
+config HISILICON_ERRATUM_162100602 + bool "Hisilicon erratum 162100602" + depends on ARM_SMMU_V3 + 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. + + If unsure, say Y. + config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" default y diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index edcb7911b3ce..261023a908a8 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -404,6 +404,7 @@ CONFIG_HISILICON_ERRATUM_1980005=y CONFIG_HISILICON_ERRATUM_162100801=y CONFIG_HISILICON_ERRATUM_162100125=y CONFIG_HISILICON_ERRATUM_162102203=y +CONFIG_HISILICON_ERRATUM_162100602=y CONFIG_QCOM_FALKOR_ERRATUM_1003=y CONFIG_QCOM_FALKOR_ERRATUM_1009=y CONFIG_QCOM_QDF2400_ERRATUM_0065=y diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index ce9fbf260a3c..0220f10cddd7 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -81,6 +81,7 @@ #define ARM64_HAS_PBHA_STAGE2 73 #define ARM64_SME 74 #define ARM64_SME_FA64 75 +#define ARM64_WORKAROUND_HISILICON_ERRATUM_162100602 76
#define ARM64_NCAPS 80
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 7f175b3aac15..6a3e948d5c2c 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -331,6 +331,13 @@ 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[] = { { @@ -533,6 +540,13 @@ 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_QCOM_FALKOR_ERRATUM_1003 { .desc = "Qualcomm Technologies Falkor/Kryo erratum 1003", 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 a55c2dab72f8..458151b7fab2 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2941,6 +2941,23 @@ static void arm_smmu_iotlb_sync(struct iommu_domain *domain, gather->pgsize, true, smmu_domain); }
+#ifdef CONFIG_HISILICON_ERRATUM_162100602 +static void arm_smmu_iotlb_sync_map(struct iommu_domain *domain, + 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)) + return; + + granule_size = 1 << __ffs(smmu_domain->domain.pgsize_bitmap); + + /* Add a SYNC command to sync io-pgtale to avoid errors in pgtable prefetch*/ + arm_smmu_tlb_inv_range_domain(iova, granule_size, granule_size, true, smmu_domain); +} +#endif + static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) { @@ -3970,6 +3987,9 @@ static struct iommu_ops arm_smmu_ops = { .unmap = arm_smmu_unmap, .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, +#endif .iova_to_phys = arm_smmu_iova_to_phys, .probe_device = arm_smmu_probe_device, .release_device = arm_smmu_release_device,