From 25479a1cdc85cac6e2f03348f9e8f3221ca6c944 Mon Sep 17 00:00:00 2001 From: Weilong Chen Date: Tue, 17 Jun 2025 19:53:14 +0800 Subject: [PATCH 1/5] cache: Workaround HiSilicon Taishan DC CVAU ascend inclusion category: feature bugzilla: 46922 CVE: NA ------------------------------------- Taishan's L1/L2 cache is inclusive, and the data is consistent. Any change of L1 does not require DC operation to brush CL in L1 to L2. It's safe that don't clean data cache by address to point of unification. Without IDC featrue, kernel needs to flush icache as well as dcache, causes performance degradation. The flaw refers to V110/V200 variant 1. Reviewed-by: Kefeng Wang Reviewed-by: Ding Tianhong Signed-off-by: Yang Yingliang Signed-off-by: Weilong Chen Reviewed-by: Kefeng Wang Signed-off-by: Yang Yingliang Reviewed-by: Weilong Chen Signed-off-by: Zheng Zengkai Signed-off-by: Qi Xi --- Documentation/arch/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 9 ++++++ arch/arm64/kernel/cpu_errata.c | 32 +++++++++++++++++++++ arch/arm64/tools/cpucaps | 1 + 4 files changed, 44 insertions(+) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index 3cf806733083c..50efebb442bc6 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -247,6 +247,8 @@ stable kernels. | Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A | | | Hip09 SMMU PMCG | | | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | TSV{110,200} | #1980005 | HISILICON_ERRATUM_1980005 | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 38d7a3cba85da..4b0fb3833616e 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1226,6 +1226,15 @@ config HISILICON_ERRATUM_162102203 If unsure, say N. +config HISILICON_ERRATUM_1980005 + bool "Hisilicon erratum IDC support" + default n + help + The HiSilicon TSV100/200 SoC support idc but report wrong value to + kernel. + + If unsure, say N. + config QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" default y diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index a78f247029aec..3bb44c8d039a1 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -55,6 +55,29 @@ is_kryo_midr(const struct arm64_cpu_capabilities *entry, int scope) return model == entry->midr_range.model; } +#ifdef CONFIG_HISILICON_ERRATUM_1980005 +static bool +hisilicon_1980005_match(const struct arm64_cpu_capabilities *entry, + int scope) +{ + static const struct midr_range idc_support_list[] = { + MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), + MIDR_REV(MIDR_HISI_TSV200, 1, 0), + { /* sentinel */ } + }; + + return is_midr_in_range_list(read_cpuid_id(), idc_support_list); +} + +static void +hisilicon_1980005_enable(const struct arm64_cpu_capabilities *__unused) +{ + cpus_set_cap(ARM64_HAS_CACHE_IDC); + arm64_ftr_reg_ctrel0.sys_val |= BIT(CTR_IDC_SHIFT); + sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCT, 0); +} +#endif + static bool has_mismatched_cache_type(const struct arm64_cpu_capabilities *entry, int scope) @@ -541,6 +564,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .cpu_enable = cpu_enable_trap_ctr_access, }, +#ifdef CONFIG_HISILICON_ERRATUM_1980005 + { + .desc = "Taishan IDC coherence workaround", + .capability = ARM64_WORKAROUND_HISILICON_1980005, + .matches = hisilicon_1980005_match, + .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .cpu_enable = hisilicon_1980005_enable, + }, +#endif #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003 { .desc = "Qualcomm Technologies Falkor/Kryo erratum 1003", diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 7369d2440af80..bd36a8735a522 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -96,6 +96,7 @@ WORKAROUND_CAVIUM_TX2_219_PRFM WORKAROUND_CAVIUM_TX2_219_TVM WORKAROUND_CLEAN_CACHE WORKAROUND_DEVICE_LOAD_ACQUIRE +WORKAROUND_HISILICON_1980005 WORKAROUND_NVIDIA_CARMEL_CNP WORKAROUND_QCOM_FALKOR_E1003 WORKAROUND_REPEAT_TLBI From 5da310f2ca2f0b1bf30452c94ff33042b53c7640 Mon Sep 17 00:00:00 2001 From: Tong Tiangen Date: Tue, 17 Jun 2025 19:53:15 +0800 Subject: [PATCH 2/5] arm64: kernel: disable CNP on LINXICORE9100 hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I7F28R CVE: NA -------------------------------- On Hisilicon LINXICORE9100 cores, sharing tlb entries on two cores when TTBRx.CNP=1 differs from the standard ARM core. This causes issues when tlb entries sharing between CPU cores. Avoid these issues by disabling CNP feature for Hisilicon LINXICORE9100 cores. Signed-off-by: Tong Tiangen Signed-off-by: Qi Xi --- Documentation/arch/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 11 +++++++++++ arch/arm64/include/asm/cputype.h | 2 ++ arch/arm64/kernel/cpu_errata.c | 14 ++++++++++++++ arch/arm64/kernel/cpufeature.c | 3 +++ arch/arm64/tools/cpucaps | 1 + config.aarch64 | 1 + 7 files changed, 34 insertions(+) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index 50efebb442bc6..d1aa9f3ad0384 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -249,6 +249,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | TSV{110,200} | #1980005 | HISILICON_ERRATUM_1980005 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | LINXICORE9100 | #162100125 | HISILICON_ERRATUM_162100125 | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 4b0fb3833616e..ed8bd7b895d36 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1235,6 +1235,17 @@ config HISILICON_ERRATUM_1980005 If unsure, say N. +config HISILICON_ERRATUM_162100125 + bool "Hisilicon erratum 162100125" + default y + help + On Hisilicon LINXICORE9100 cores, sharing tlb entries on two cores when + TTBRx.CNP=1 differs from the standard ARM core. This causes issues when + tlb entries sharing between CPU cores. Avoid these issues by disabling + CNP support for Hisilicon LINXICORE9100 cores. + + 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/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 488f8e7513495..5871b5b941ba5 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -129,6 +129,7 @@ #define FUJITSU_CPU_PART_A64FX 0x001 #define HISI_CPU_PART_TSV110 0xD01 +#define HISI_CPU_PART_LINXICORE9100 0xD02 #define APPLE_CPU_PART_M1_ICESTORM 0x022 #define APPLE_CPU_PART_M1_FIRESTORM 0x023 @@ -202,6 +203,7 @@ #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX) #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) +#define MIDR_HISI_LINXICORE9100 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_LINXICORE9100) #define MIDR_APPLE_M1_ICESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) #define MIDR_APPLE_M1_FIRESTORM MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) #define MIDR_APPLE_M1_ICESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO) diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index 3bb44c8d039a1..3fbd0f1b66fca 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -289,6 +289,13 @@ static const struct midr_range cavium_erratum_30115_cpus[] = { }; #endif +#ifdef CONFIG_HISILICON_ERRATUM_162100125 +static const struct midr_range hisilicon_erratum_162100125_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[] = { { @@ -573,6 +580,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = { .cpu_enable = hisilicon_1980005_enable, }, #endif +#ifdef CONFIG_HISILICON_ERRATUM_162100125 + { + .desc = "Hisilicon erratum 162100125", + .capability = ARM64_WORKAROUND_HISILICON_ERRATUM_162100125, + ERRATA_MIDR_RANGE_LIST(hisilicon_erratum_162100125_cpus), + }, +#endif #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003 { .desc = "Qualcomm Technologies Falkor/Kryo erratum 1003", diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 58156edbcf015..61cfe9cb200fd 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1629,6 +1629,9 @@ has_useable_cnp(const struct arm64_cpu_capabilities *entry, int scope) if (is_kdump_kernel()) return false; + if (cpus_have_final_cap(ARM64_WORKAROUND_HISILICON_ERRATUM_162100125)) + return false; + if (cpus_have_cap(ARM64_WORKAROUND_NVIDIA_CARMEL_CNP)) return false; diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index bd36a8735a522..4635f3d232d92 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -97,6 +97,7 @@ WORKAROUND_CAVIUM_TX2_219_TVM WORKAROUND_CLEAN_CACHE WORKAROUND_DEVICE_LOAD_ACQUIRE WORKAROUND_HISILICON_1980005 +WORKAROUND_HISILICON_ERRATUM_162100125 WORKAROUND_NVIDIA_CARMEL_CNP WORKAROUND_QCOM_FALKOR_E1003 WORKAROUND_REPEAT_TLBI diff --git a/config.aarch64 b/config.aarch64 index 3e2d4bad93194..4f552cb0d7028 100644 --- a/config.aarch64 +++ b/config.aarch64 @@ -398,6 +398,7 @@ CONFIG_QCOM_FALKOR_ERRATUM_E1041=y CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y CONFIG_ROCKCHIP_ERRATUM_3588001=y CONFIG_SOCIONEXT_SYNQUACER_PREITS=y +CONFIG_HISILICON_ERRATUM_162100125=y # end of ARM errata workarounds via the alternatives framework CONFIG_ARM64_4K_PAGES=y From 1438d38803f078cf6b994922731f4be39ae3f1e8 Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Tue, 17 Jun 2025 19:53:16 +0800 Subject: [PATCH 3/5] irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801 driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7C103 -------------------------------------------------------------------------- When enabled GICv4.1 in hip09, there are some invalid vPE configurations in configuration table for some situations, which will cause some vSGI interrupts lost. To fix the issue, need to send vinvall command after vmovp. Signed-off-by: Nianyao Tang Signed-off-by: Xiang Chen Signed-off-by: CaiJian Signed-off-by: Qi Xi --- Documentation/arch/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 10 ++++++ config.aarch64 | 1 + drivers/irqchip/irq-gic-v3-its.c | 36 ++++++++++++++++----- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index d1aa9f3ad0384..baf31a3108d14 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -249,6 +249,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | TSV{110,200} | #1980005 | HISILICON_ERRATUM_1980005 | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_162100801 | ++----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | LINXICORE9100 | #162100125 | HISILICON_ERRATUM_162100125 | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index ed8bd7b895d36..eb05b9f925c1d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1235,6 +1235,16 @@ config HISILICON_ERRATUM_1980005 If unsure, say N. +config HISILICON_ERRATUM_162100801 + bool "Hip09 162100801 erratum support" + default y + help + When enabled GICv4.1 in hip09, there are some invalid vPE config + in configuration tables for some situation, which will cause vSGI + interrupts lost. So fix it by sending vinvall commands after vmovp. + + If unsure, say Y. + config HISILICON_ERRATUM_162100125 bool "Hisilicon erratum 162100125" default y diff --git a/config.aarch64 b/config.aarch64 index 4f552cb0d7028..a93972feb2cbd 100644 --- a/config.aarch64 +++ b/config.aarch64 @@ -398,6 +398,7 @@ CONFIG_QCOM_FALKOR_ERRATUM_E1041=y CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y CONFIG_ROCKCHIP_ERRATUM_3588001=y CONFIG_SOCIONEXT_SYNQUACER_PREITS=y +CONFIG_HISILICON_ERRATUM_162100801=y CONFIG_HISILICON_ERRATUM_162100125=y # end of ARM errata workarounds via the alternatives framework diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index b1e60c13c1e1e..d8f6b4950d161 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -43,6 +43,7 @@ #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) #define ITS_FLAGS_FORCE_NON_SHAREABLE (1ULL << 3) +#define ITS_FLAGS_WORKAROUND_HISILICON_162100801 (1ULL << 4) #define RD_LOCAL_LPI_ENABLED BIT(0) #define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1) @@ -1313,6 +1314,14 @@ static void its_send_vmapp(struct its_node *its, its_send_single_vcommand(its, its_build_vmapp_cmd, &desc); } +static void its_send_vinvall(struct its_node *its, struct its_vpe *vpe) +{ + struct its_cmd_desc desc; + + desc.its_vinvall_cmd.vpe = vpe; + its_send_single_vcommand(its, its_build_vinvall_cmd, &desc); +} + static void its_send_vmovp(struct its_vpe *vpe) { struct its_cmd_desc desc = {}; @@ -1352,19 +1361,14 @@ static void its_send_vmovp(struct its_vpe *vpe) desc.its_vmovp_cmd.col = &its->collections[col_id]; its_send_single_vcommand(its, its_build_vmovp_cmd, &desc); + if (is_v4_1(its) && (its->flags & + ITS_FLAGS_WORKAROUND_HISILICON_162100801)) + its_send_vinvall(its, vpe); } raw_spin_unlock_irqrestore(&vmovp_lock, flags); } -static void its_send_vinvall(struct its_node *its, struct its_vpe *vpe) -{ - struct its_cmd_desc desc; - - desc.its_vinvall_cmd.vpe = vpe; - its_send_single_vcommand(its, its_build_vinvall_cmd, &desc); -} - static void its_send_vinv(struct its_device *dev, u32 event_id) { struct its_cmd_desc desc; @@ -4764,6 +4768,14 @@ static bool its_set_non_coherent(void *data) return true; } +static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data) +{ + struct its_node *its = data; + + its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801; + return true; +} + static const struct gic_quirk its_quirks[] = { #ifdef CONFIG_CAVIUM_ERRATUM_22375 { @@ -4817,6 +4829,14 @@ static const struct gic_quirk its_quirks[] = { .mask = 0xffffffff, .init = its_enable_rk3588001, }, +#endif +#ifdef CONFIG_HISILICON_ERRATUM_162100801 + { + .desc = "ITS: Hip09 erratum 162100801", + .iidr = 0x00051736, + .mask = 0xffffffff, + .init = its_enable_quirk_hip09_162100801, + }, #endif { .desc = "ITS: non-coherent attribute", From a6bc35a1c985da02f23cc7eff1bb3bdcad7f49ca Mon Sep 17 00:00:00 2001 From: Zhang Zekun Date: Tue, 17 Jun 2025 19:53:17 +0800 Subject: [PATCH 4/5] iommu/arm-smmu-v3: Enable iotlb_sync_map according to SMMU_IIDR hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I913T5 CVE: NA --------------------------------------------------- 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 Signed-off-by: Qi Xi --- Documentation/arch/arm64/silicon-errata.rst | 1 + arch/arm64/Kconfig | 12 +++++++++ config.aarch64 | 1 + drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 28 +++++++++++++++++++++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 5 files changed, 43 insertions(+) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst index baf31a3108d14..03d12015cef5f 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -253,6 +253,7 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | LINXICORE9100 | #162100125 | HISILICON_ERRATUM_162100125 | +----------------+-----------------+-----------------+-----------------------------+ +| 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 eb05b9f925c1d..0ff6ad1b6b5d3 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1256,6 +1256,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 QCOM_FALKOR_ERRATUM_1003 bool "Falkor E1003: Incorrect translation due to ASID change" default y diff --git a/config.aarch64 b/config.aarch64 index a93972feb2cbd..451fb65aecb3a 100644 --- a/config.aarch64 +++ b/config.aarch64 @@ -391,6 +391,7 @@ CONFIG_CAVIUM_TX2_ERRATUM_219=y CONFIG_FUJITSU_ERRATUM_010001=y CONFIG_HISILICON_ERRATUM_161600802=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/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 68b81f9c2f4b1..166982b67cd04 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2525,6 +2525,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 (!(smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_MAP)) + 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) { @@ -2880,6 +2897,9 @@ static struct iommu_ops arm_smmu_ops = { .unmap_pages = arm_smmu_unmap_pages, .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, .enable_nesting = arm_smmu_enable_nesting, .free = arm_smmu_domain_free, @@ -3661,6 +3681,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_REVISION, 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/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index 9915850dd4dbf..33c81035021c0 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -652,6 +652,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; struct arm_smmu_cmdq cmdq; From a2bb80bff97388b042d5098c6b1ca4fbcf8dfb50 Mon Sep 17 00:00:00 2001 From: Zhang Zekun Date: Tue, 17 Jun 2025 19:53:18 +0800 Subject: [PATCH 5/5] iommu/arm-smmu-v3: Reducing the CMD_SYNC times hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9G9TI ---------------------------------------- Benifiting from the hardware same address blocking mechanism. We only need to send the CMD_SYNC when creating pte entry other than lvl 3, this can reduce the amounts of CMD_SYNC times sent to avoiding the errata. Detecting the hardware ability by read the SMMU_USER_CONFIG1. Fixes: 46f0c5798ba5 ("iommu/arm-smmu-v3: Enable iotlb_sync_map according to SMMU_IIDR") Signed-off-by: Zhang Zekun Signed-off-by: Qi Xi --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 57 +++++++++++++++++++-- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 3 ++ drivers/iommu/io-pgtable-arm.c | 4 ++ 3 files changed, 59 insertions(+), 5 deletions(-) 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 166982b67cd04..6e4b40c97f3c0 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2005,6 +2005,14 @@ static void arm_smmu_tlb_inv_page_nosync(struct iommu_iotlb_gather *gather, 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) { + arm_smmu_tlb_inv_range_domain(iova, granule, granule, true, cookie); + return; + } +#endif arm_smmu_tlb_inv_range_domain(iova, size, granule, false, cookie); } @@ -2535,6 +2543,9 @@ static void arm_smmu_iotlb_sync_map(struct iommu_domain *domain, if (!(smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_MAP)) return; + if (smmu_domain->smmu->options & ARM_SMMU_OPT_SYNC_BATCH) + return; + granule_size = 1 << __ffs(smmu_domain->domain.pgsize_bitmap); /* Add a SYNC command to sync io-pgtale to avoid errors in pgtable prefetch*/ @@ -3487,6 +3498,46 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu) } } +#ifdef CONFIG_HISILICON_ERRATUM_162100602 +static void hisi_smmu_check_errata(struct arm_smmu_device *smmu) +{ + u32 reg, i; + + /* IIDR */ + reg = readl_relaxed(smmu->base + ARM_SMMU_IIDR); + if (!(FIELD_GET(IIDR_VARIANT, reg) == 0x3) || + !(FIELD_GET(IIDR_REVISION, reg) == 0x2)) + 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++) { + unsigned long val; + + val = (reg >> 2 * i) & GENMASK(1, 0); + switch (PAGE_SIZE) { + case SZ_4K: + if (!val) + return; + break; + case SZ_16K: + if (!val || val == 0x1) + return; + break; + case SZ_64K: + if (!val || val == 0x1 || val == 0x3) + return; + break; + default: + return; + } + } + smmu->options |= ARM_SMMU_OPT_SYNC_BATCH; +} +#endif + static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) { u32 reg; @@ -3682,11 +3733,7 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) } #ifdef CONFIG_HISILICON_ERRATUM_162100602 - /* IIDR */ - 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; + hisi_smmu_check_errata(smmu); #endif if (arm_smmu_ops.pgsize_bitmap == -1UL) 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 33c81035021c0..f4cd0f6d2a0dd 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -129,6 +129,8 @@ #define ARM_SMMU_GERROR_IRQ_CFG1 0x70 #define ARM_SMMU_GERROR_IRQ_CFG2 0x74 +#define ARM_SMMU_USER_CFG1 0xe04 + #define ARM_SMMU_STRTAB_BASE 0x80 #define STRTAB_BASE_RA (1UL << 62) #define STRTAB_BASE_ADDR_MASK GENMASK_ULL(51, 6) @@ -653,6 +655,7 @@ struct arm_smmu_device { #define ARM_SMMU_OPT_MSIPOLL (1 << 2) #define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3) #define ARM_SMMU_OPT_SYNC_MAP (1 << 4) +#define ARM_SMMU_OPT_SYNC_BATCH (1 << 5) u32 options; struct arm_smmu_cmdq cmdq; diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 934dc97f5df9e..7a931531d4b12 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -380,6 +380,10 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, pte = arm_lpae_install_table(cptep, ptep, 0, data); if (pte) __arm_lpae_free_pages(cptep, tblsz, cfg); +#ifdef CONFIG_HISILICON_ERRATUM_162100602 + if (lvl <= 2) + 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)) { __arm_lpae_sync_pte(ptep, 1, cfg); }