diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index fa44c5cfc2cdf163707f2d32afb74b8dedb32bdf..d790d19d8f9bbc9ae1c66011565603073d0aa533 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -147,6 +147,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | LINXICORE9100 | #162100125 | HISILICON_ERRATUM_162100125 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | SMMUv3 | #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 a2249a54139d76d84c97bf2b99bb2122e655591f..34030bd1319f7b4537f4fe49dc6d7932007805a8 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -766,6 +766,18 @@ config HISILICON_ERRATUM_162100125 If unsure, say Y. +config HISILICON_ERRATUM_162100602 + bool "Hisilicon erratum 162100602" + depends on ARM_SMMU_V3 && ARCH_HISI + default y + help + 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 HISILICON_ERRATUM_162102203 bool "Hisilicon erratum 162102203" depends on EFI && ACPI @@ -778,19 +790,6 @@ 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 HISILICON_ERRATUM_162100803 bool "Hip09/10/10c/12 162100803/162200807/162400807/165010802 erratum support" default y diff --git a/arch/arm64/configs/tencent.config b/arch/arm64/configs/tencent.config index c0f979728a355d4105c551fdb7d0954a1802dd78..3c9fd7ac4e4ab38621c323b1deeb97c405b7d6e0 100644 --- a/arch/arm64/configs/tencent.config +++ b/arch/arm64/configs/tencent.config @@ -1516,3 +1516,4 @@ CONFIG_HISI_L3T_PMU=m CONFIG_HISI_LPDDRC_PMU=m CONFIG_HISILICON_HW_METRIC=y CONFIG_HISILICON_ERRATUM_162100803=y +CONFIG_HISILICON_ERRATUM_162100602=y diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index be9167f0dc7fcc60ebf020e0698b4c5115e83397..432effda3fafd18429fcbaf6e083f2ab82218602 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -63,7 +63,6 @@ #define ARM64_HAS_ECV 53 #define ARM64_WORKAROUND_HISILICON_1980005 54 #define ARM64_WORKAROUND_HISILICON_ERRATUM_162100125 55 -#define ARM64_WORKAROUND_HISILICON_ERRATUM_162100602 56 #define ARM64_HAS_TIDCP1 57 #define ARM64_HAS_FGT 58 #define ARM64_HAFT 59 diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index f8b85fc91e76d13aaf895b5134f4c59b74b1062e..4ecc6888f4884d6291d3e3110c29816e09ca54d7 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -784,13 +784,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[] = { { @@ -981,13 +974,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_QCOM_FALKOR_ERRATUM_1003 { .desc = "Qualcomm Technologies Falkor/Kryo erratum 1003", diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 64573ae8f31a25778f6f44efdef7b61126910037..760cfb14e7b595b86ef26ff4c9dab4a79ab79111 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -2594,19 +2594,19 @@ 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) +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)) + if (!(smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_MAP)) return; - if(smmu_domain->smmu) - arm_smmu_tlb_inv_context(smmu_domain); - //granule_size = 1 << __ffs(smmu_domain->domain.pgsize_bitmap); + 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); + arm_smmu_tlb_inv_range_domain(iova, granule_size, granule_size, true, smmu_domain); } #endif @@ -3970,6 +3970,14 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) smmu->oas = 48; } +#ifdef CONFIG_HISILICON_ERRATUM_162100602 + /* IIDR */ + reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR); + if (FIELD_GET(IIDR_VARIANT, reg) == 0x3 && + FIELD_GET(IIDR_REVISON, reg) == 0x2) + smmu->options |= ARM_SMMU_OPT_SYNC_MAP; +#endif + if (arm_smmu_ops.pgsize_bitmap == -1UL) arm_smmu_ops.pgsize_bitmap = smmu->pgsize_bitmap; else diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h index b19b6cae9b5e8437c51958989d127ee0c50b16a1..8d9b95e3267eadc1402a3186c7db8b8559d637f3 100644 --- a/drivers/iommu/arm-smmu.h +++ b/drivers/iommu/arm-smmu.h @@ -39,6 +39,10 @@ /* Auxiliary Configuration register */ #define ARM_SMMU_GR0_sACR 0x10 +#define ARM_SMMU_IIDR 0x18 +#define IIDR_VARIANT GENMASK(19, 16) +#define IIDR_REVISON GENMASK(15, 12) + /* Identification registers */ #define ARM_SMMU_GR0_ID0 0x20 #define ID0_S1TS BIT(30) @@ -244,6 +248,7 @@ struct arm_smmu_device { #define ARM_SMMU_FEAT_EXIDS (1 << 12) u32 features; +#define ARM_SMMU_OPT_SYNC_MAP (1 << 0) enum arm_smmu_arch_version version; enum arm_smmu_implementation model; const struct arm_smmu_impl *impl;