diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index a9441bfebb0d46cedc60acd25cd3983e98abe686..1f06e18a1859849c0f837c06de511650c03eb842 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 c5eca65c27fc70fb464259c8c7591ebfde32b9e3..851d24a35e4e1b45bef309557c960e1ebda48985 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 36dda61d5a5add054aa379af557b94132c5bc941..12e4828c9cd147bf58117e727f86a9b773b91a7e 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 ce9fbf260a3cf20c0cbab1ede4f5982dbf3c7ac2..0220f10cddd7ff1fcb987a587f9a06c6eaf227b7 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 7f175b3aac152f3b7d9b2e24dc347b4b72cd0a45..6a3e948d5c2c0e7beba9b8f9a97b7b1b6f6de71b 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 a55c2dab72f864fb5c460fbd63d7735015775200..458151b7fab2649822eee51361d206821678d545 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,