From 9447c2e24f160a9a79d1fc540ab03f5aa27c0308 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 27 Oct 2019 14:55:34 +0100 Subject: [PATCH] 4.19-stable patches added patches: arm64-enable-workaround-for-cavium-tx2-erratum-219-when-running-smt.patch edac-ghes-fix-use-after-free-in-ghes_edac-remove-path.patch parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch --- ...ium-tx2-erratum-219-when-running-smt.patch | 78 +++++++++++++++++++ ...-after-free-in-ghes_edac-remove-path.patch | 76 ++++++++++++++++++ ...-vmap-memory-leak-in-ioremap-iounmap.patch | 60 ++++++++++++++ queue-4.19/series | 3 + 4 files changed, 217 insertions(+) create mode 100644 queue-4.19/arm64-enable-workaround-for-cavium-tx2-erratum-219-when-running-smt.patch create mode 100644 queue-4.19/edac-ghes-fix-use-after-free-in-ghes_edac-remove-path.patch create mode 100644 queue-4.19/parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch diff --git a/queue-4.19/arm64-enable-workaround-for-cavium-tx2-erratum-219-when-running-smt.patch b/queue-4.19/arm64-enable-workaround-for-cavium-tx2-erratum-219-when-running-smt.patch new file mode 100644 index 00000000000..698861ace06 --- /dev/null +++ b/queue-4.19/arm64-enable-workaround-for-cavium-tx2-erratum-219-when-running-smt.patch @@ -0,0 +1,78 @@ +From 93916beb70143c46bf1d2bacf814be3a124b253b Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Tue, 9 Apr 2019 16:26:21 +0100 +Subject: arm64: Enable workaround for Cavium TX2 erratum 219 when running SMT + +From: Marc Zyngier + +commit 93916beb70143c46bf1d2bacf814be3a124b253b upstream. + +It appears that the only case where we need to apply the TX2_219_TVM +mitigation is when the core is in SMT mode. So let's condition the +enabling on detecting a CPU whose MPIDR_EL1.Aff0 is non-zero. + +Cc: +Signed-off-by: Marc Zyngier +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/cpu_errata.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +--- a/arch/arm64/kernel/cpu_errata.c ++++ b/arch/arm64/kernel/cpu_errata.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + static bool __maybe_unused + is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope) +@@ -618,6 +619,30 @@ check_branch_predictor(const struct arm6 + return (need_wa > 0); + } + ++static const __maybe_unused struct midr_range tx2_family_cpus[] = { ++ MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), ++ MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), ++ {}, ++}; ++ ++static bool __maybe_unused ++needs_tx2_tvm_workaround(const struct arm64_cpu_capabilities *entry, ++ int scope) ++{ ++ int i; ++ ++ if (!is_affected_midr_range_list(entry, scope) || ++ !is_hyp_mode_available()) ++ return false; ++ ++ for_each_possible_cpu(i) { ++ if (MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0) != 0) ++ return true; ++ } ++ ++ return false; ++} ++ + #ifdef CONFIG_HARDEN_EL2_VECTORS + + static const struct midr_range arm64_harden_el2_vectors[] = { +@@ -802,6 +827,14 @@ const struct arm64_cpu_capabilities arm6 + .matches = has_cortex_a76_erratum_1463225, + }, + #endif ++#ifdef CONFIG_CAVIUM_TX2_ERRATUM_219 ++ { ++ .desc = "Cavium ThunderX2 erratum 219 (KVM guest sysreg trapping)", ++ .capability = ARM64_WORKAROUND_CAVIUM_TX2_219_TVM, ++ ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), ++ .matches = needs_tx2_tvm_workaround, ++ }, ++#endif + { + } + }; diff --git a/queue-4.19/edac-ghes-fix-use-after-free-in-ghes_edac-remove-path.patch b/queue-4.19/edac-ghes-fix-use-after-free-in-ghes_edac-remove-path.patch new file mode 100644 index 00000000000..820a86f64fc --- /dev/null +++ b/queue-4.19/edac-ghes-fix-use-after-free-in-ghes_edac-remove-path.patch @@ -0,0 +1,76 @@ +From 1e72e673b9d102ff2e8333e74b3308d012ddf75b Mon Sep 17 00:00:00 2001 +From: James Morse +Date: Mon, 14 Oct 2019 18:19:18 +0100 +Subject: EDAC/ghes: Fix Use after free in ghes_edac remove path + +From: James Morse + +commit 1e72e673b9d102ff2e8333e74b3308d012ddf75b upstream. + +ghes_edac models a single logical memory controller, and uses a global +ghes_init variable to ensure only the first ghes_edac_register() will +do anything. + +ghes_edac is registered the first time a GHES entry in the HEST is +probed. There may be multiple entries, so subsequent attempts to +register ghes_edac are silently ignored as the work has already been +done. + +When a GHES entry is unregistered, it calls ghes_edac_unregister(), +which free()s the memory behind the global variables in ghes_edac. + +But there may be multiple GHES entries, the next call to +ghes_edac_unregister() will dereference the free()d memory, and attempt +to free it a second time. + +This may also be triggered on a platform with one GHES entry, if the +driver is unbound/re-bound and unbound. The re-bind step will do +nothing because of ghes_init, the second unbind will then do the same +work as the first. + +Doing the unregister work on the first call is unsafe, as another +CPU may be processing a notification in ghes_edac_report_mem_error(), +using the memory we are about to free. + +ghes_init is already half of the reference counting. We only need +to do the register work for the first call, and the unregister work +for the last. Add the unregister check. + +This means we no longer free ghes_edac's memory while there are +GHES entries that may receive a notification. + +This was detected by KASAN and DEBUG_TEST_DRIVER_REMOVE. + + [ bp: merge into a single patch. ] + +Fixes: 0fe5f281f749 ("EDAC, ghes: Model a single, logical memory controller") +Reported-by: John Garry +Signed-off-by: James Morse +Signed-off-by: Borislav Petkov +Cc: linux-edac +Cc: Mauro Carvalho Chehab +Cc: Robert Richter +Cc: Tony Luck +Cc: +Link: https://lkml.kernel.org/r/20191014171919.85044-2-james.morse@arm.com +Link: https://lkml.kernel.org/r/304df85b-8b56-b77e-1a11-aa23769f2e7c@huawei.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/edac/ghes_edac.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/edac/ghes_edac.c ++++ b/drivers/edac/ghes_edac.c +@@ -532,7 +532,11 @@ void ghes_edac_unregister(struct ghes *g + if (!ghes_pvt) + return; + ++ if (atomic_dec_return(&ghes_init)) ++ return; ++ + mci = ghes_pvt->mci; ++ ghes_pvt = NULL; + edac_mc_del_mc(mci->pdev); + edac_mc_free(mci); + } diff --git a/queue-4.19/parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch b/queue-4.19/parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch new file mode 100644 index 00000000000..eb274191dfb --- /dev/null +++ b/queue-4.19/parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch @@ -0,0 +1,60 @@ +From 513f7f747e1cba81f28a436911fba0b485878ebd Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Fri, 4 Oct 2019 19:23:37 +0200 +Subject: parisc: Fix vmap memory leak in ioremap()/iounmap() + +From: Helge Deller + +commit 513f7f747e1cba81f28a436911fba0b485878ebd upstream. + +Sven noticed that calling ioremap() and iounmap() multiple times leads +to a vmap memory leak: + vmap allocation for size 4198400 failed: + use vmalloc= to increase size + +It seems we missed calling vunmap() in iounmap(). + +Signed-off-by: Helge Deller +Noticed-by: Sven Schnelle +Cc: # v3.16+ +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/mm/ioremap.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/arch/parisc/mm/ioremap.c ++++ b/arch/parisc/mm/ioremap.c +@@ -3,7 +3,7 @@ + * arch/parisc/mm/ioremap.c + * + * (C) Copyright 1995 1996 Linus Torvalds +- * (C) Copyright 2001-2006 Helge Deller ++ * (C) Copyright 2001-2019 Helge Deller + * (C) Copyright 2005 Kyle McMartin + */ + +@@ -84,7 +84,7 @@ void __iomem * __ioremap(unsigned long p + addr = (void __iomem *) area->addr; + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, pgprot)) { +- vfree(addr); ++ vunmap(addr); + return NULL; + } + +@@ -92,9 +92,11 @@ void __iomem * __ioremap(unsigned long p + } + EXPORT_SYMBOL(__ioremap); + +-void iounmap(const volatile void __iomem *addr) ++void iounmap(const volatile void __iomem *io_addr) + { +- if (addr > high_memory) +- return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); ++ unsigned long addr = (unsigned long)io_addr & PAGE_MASK; ++ ++ if (is_vmalloc_addr((void *)addr)) ++ vunmap((void *)addr); + } + EXPORT_SYMBOL(iounmap); diff --git a/queue-4.19/series b/queue-4.19/series index 4d96270c252..f7b0570c366 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -68,3 +68,6 @@ mm-page_owner-don-t-access-uninitialized-memmaps-when-reading-proc-pagetypeinfo. hugetlbfs-don-t-access-uninitialized-memmaps-in-pfn_range_valid_gigantic.patch mm-memory-failure-poison-read-receives-sigkill-instead-of-sigbus-if-mmaped-more-than-once.patch xtensa-drop-export_symbol-for-outs-ins.patch +parisc-fix-vmap-memory-leak-in-ioremap-iounmap.patch +edac-ghes-fix-use-after-free-in-ghes_edac-remove-path.patch +arm64-enable-workaround-for-cavium-tx2-erratum-219-when-running-smt.patch -- 2.47.2