diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 2aca373a703843367541bf90d877a7352553a3cb..02f6dff029ed61a04b5f7a0e73f418f408e3e7d9 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1180,6 +1180,19 @@ config HISILICON_ERRATUM_1980005 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 3d3503f936cac69608dd55df960d4bbc73db5a08..12789c1fa921de5701e16da887e7d21c947c83d4 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -400,6 +400,7 @@ CONFIG_CAVIUM_TX2_ERRATUM_219=y CONFIG_FUJITSU_ERRATUM_010001=y CONFIG_HISILICON_ERRATUM_161600802=y CONFIG_HISILICON_ERRATUM_162100125=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/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index a686a96d966aa652d70c834b8fd8259b7478403f..c569e6c0ac07f274410991b2d3760e2709e61997 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -360,6 +360,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[] = { { @@ -591,6 +598,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_HISILICON_ERRATUM_1980005 { .desc = "Hisilicon erratum 1980005 (IDC)", diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps index 0b62edb918764132bfa87d20d4b340ecd9dd8efa..569ecec76c16767d1e6d33519a59fbe2a623f734 100644 --- a/arch/arm64/tools/cpucaps +++ b/arch/arm64/tools/cpucaps @@ -103,3 +103,4 @@ WORKAROUND_SPECULATIVE_AT WORKAROUND_HISILICON_ERRATUM_162100125 WORKAROUND_HISI_HIP08_RU_PREFETCH WORKAROUND_HISILICON_1980005 +WORKAROUND_HISILICON_ERRATUM_162100602 diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index bf1b9252a8dab1be7fca445e5b3842806f363879..af6e32d56ecefd571fa12f57a9212a6f948b6eee 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -684,6 +684,9 @@ static bool ghes_do_proc(struct ghes *ghes, arch_apei_report_mem_error(sev, mem_err); queued = ghes_handle_memory_failure(gdata, sev); +#ifdef CONFIG_ASCEND_RAS_FEATURES + continue; +#endif } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { ghes_handle_aer(gdata); 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 5055a66644afc9ee35961fab12207140e2b09c73..d0422bb137247c3e5cd75936fdb6bb09ac9af6c1 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2528,6 +2528,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) { @@ -2883,6 +2900,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, diff --git a/include/linux/mm.h b/include/linux/mm.h index 80bacc4da324c38cadaa3cc9034071b5687cc694..4246015259ffd4b8fde2739a39d65b8f9e094745 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -395,6 +395,10 @@ extern unsigned int kobjsize(const void *objp); # define VM_SHARE_POOL VM_NONE #endif +#if defined(CONFIG_ASCEND_RAS_FEATURES) +#define ASCEND_HWPOISON_MAGIC_NUM 0xABAB +#endif + #ifndef VM_GROWSUP # define VM_GROWSUP VM_NONE #endif @@ -3878,6 +3882,10 @@ extern int __get_huge_page_for_hwpoison(unsigned long pfn, int flags, void num_poisoned_pages_inc(unsigned long pfn); void num_poisoned_pages_sub(unsigned long pfn, long i); struct task_struct *task_early_kill(struct task_struct *tsk, int force_early); +#ifdef CONFIG_ASCEND_RAS_FEATURES +extern void collect_procs(struct page *page, struct list_head *tokill, + int force_early); +#endif #else static inline void memory_failure_queue(unsigned long pfn, int flags) { diff --git a/mm/Kconfig b/mm/Kconfig index ff0c36f42ca8ec4c0c564057dc3ab54be502261f..fe1750f2fd8acc711df30d8a24cd9cd784d59668 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -1323,6 +1323,17 @@ config ASCEND_OOM 0: disable oom killer 1: enable oom killer (default,compatible with mainline) +config ASCEND_RAS_FEATURES + bool "ACPI RAS features for ascend scenarios" + default n + depends on ACPI && ARM64 + help + ACPI RAS features developed to support some of special cases in ascend + scenarios. If you don't know the actual usage of these features don't + open this config. + + If not sure, say no. + source "mm/damon/Kconfig" endmenu diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 4d6e43c88489a0ef1755656a7512577902374496..b90e7dbf7430535328ccf511faad47660227157e 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -582,6 +582,11 @@ struct task_struct *task_early_kill(struct task_struct *tsk, int force_early) { if (!tsk->mm) return NULL; + +#ifdef CONFIG_ASCEND_RAS_FEATURES + if (force_early == ASCEND_HWPOISON_MAGIC_NUM) + return tsk; +#endif /* * Comparing ->mm here because current task might represent * a subthread, while tsk always points to the main thread. @@ -704,8 +709,13 @@ static void collect_procs_fsdax(struct page *page, /* * Collect the processes who have the corrupted page mapped to kill. */ +#ifdef CONFIG_ASCEND_RAS_FEATURES +void collect_procs(struct page *page, struct list_head *tokill, + int force_early) +#else static void collect_procs(struct page *page, struct list_head *tokill, int force_early) +#endif { if (!page->mapping) return; @@ -716,6 +726,9 @@ static void collect_procs(struct page *page, struct list_head *tokill, else collect_procs_file(page, tokill, force_early); } +#ifdef CONFIG_ASCEND_RAS_FEATURES +EXPORT_SYMBOL_GPL(collect_procs); +#endif struct hwpoison_walk { struct to_kill tk;