]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 21 Feb 2018 09:40:17 +0000 (10:40 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 21 Feb 2018 09:40:17 +0000 (10:40 +0100)
added patches:
x86-mm-mm-hwpoison-don-t-unconditionally-unmap-kernel-1-1-pages.patch

queue-4.14/acpi-apei-remove-arch_apei_flush_tlb_one.patch [deleted file]
queue-4.14/series
queue-4.14/x86-mm-mm-hwpoison-don-t-unconditionally-unmap-kernel-1-1-pages.patch [new file with mode: 0644]
queue-4.14/x86-mm-rename-flush_tlb_single-and-flush_tlb_one-to-__flush_tlb_one_.patch

diff --git a/queue-4.14/acpi-apei-remove-arch_apei_flush_tlb_one.patch b/queue-4.14/acpi-apei-remove-arch_apei_flush_tlb_one.patch
deleted file mode 100644 (file)
index 0509875..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-From 4a75aeacda3c2455954596593d89187df5420d0a Mon Sep 17 00:00:00 2001
-From: James Morse <james.morse@arm.com>
-Date: Mon, 6 Nov 2017 18:44:27 +0000
-Subject: ACPI / APEI: Remove arch_apei_flush_tlb_one()
-
-From: James Morse <james.morse@arm.com>
-
-commit 4a75aeacda3c2455954596593d89187df5420d0a upstream.
-
-Nothing calls arch_apei_flush_tlb_one() anymore, instead relying on
-__set_pte_vaddr() to do the invalidation when called from clear_fixmap()
-Remove arch_apei_flush_tlb_one().
-
-Signed-off-by: James Morse <james.morse@arm.com>
-Reviewed-by: Borislav Petkov <bp@suse.de>
-Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-Cc: All applicable <stable@vger.kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- arch/x86/kernel/acpi/apei.c |    5 -----
- include/acpi/apei.h         |    1 -
- 2 files changed, 6 deletions(-)
-
---- a/arch/x86/kernel/acpi/apei.c
-+++ b/arch/x86/kernel/acpi/apei.c
-@@ -52,8 +52,3 @@ void arch_apei_report_mem_error(int sev,
-       apei_mce_report_mem_error(sev, mem_err);
- #endif
- }
--
--void arch_apei_flush_tlb_one(unsigned long addr)
--{
--      __flush_tlb_one(addr);
--}
---- a/include/acpi/apei.h
-+++ b/include/acpi/apei.h
-@@ -51,7 +51,6 @@ int erst_clear(u64 record_id);
- int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
- void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
--void arch_apei_flush_tlb_one(unsigned long addr);
- #endif
- #endif
index 8297628c5111662d0dc227cade5a6021909b7234..2bbddcf59954df922c87e3d26d5a5b53faf330e3 100644 (file)
@@ -81,7 +81,6 @@ kmemcheck-stop-using-gfp_notrack-and-slab_notrack.patch
 kmemcheck-remove-whats-left-of-notrack-flags.patch
 kmemcheck-rip-it-out.patch
 kmemcheck-rip-it-out-for-real.patch
-acpi-apei-remove-arch_apei_flush_tlb_one.patch
 x86-mm-rename-flush_tlb_single-and-flush_tlb_one-to-__flush_tlb_one_.patch
 selftests-x86-mpx-fix-incorrect-bounds-with-old-_sigfault.patch
 x86-cpu-rename-cpu_data.x86_mask-to-cpu_data.x86_stepping.patch
@@ -150,3 +149,4 @@ alsa-usb-add-more-device-quirks-for-usb-dsd-devices.patch
 alsa-seq-fix-racy-pool-initializations.patch
 mvpp2-fix-multicast-address-filter.patch
 usb-move-usb_uhci_big_endian_-out-of-usb_support.patch
+x86-mm-mm-hwpoison-don-t-unconditionally-unmap-kernel-1-1-pages.patch
diff --git a/queue-4.14/x86-mm-mm-hwpoison-don-t-unconditionally-unmap-kernel-1-1-pages.patch b/queue-4.14/x86-mm-mm-hwpoison-don-t-unconditionally-unmap-kernel-1-1-pages.patch
new file mode 100644 (file)
index 0000000..eeedc8a
--- /dev/null
@@ -0,0 +1,184 @@
+From fd0e786d9d09024f67bd71ec094b110237dc3840 Mon Sep 17 00:00:00 2001
+From: Tony Luck <tony.luck@intel.com>
+Date: Thu, 25 Jan 2018 14:23:48 -0800
+Subject: x86/mm, mm/hwpoison: Don't unconditionally unmap kernel 1:1 pages
+
+From: Tony Luck <tony.luck@intel.com>
+
+commit fd0e786d9d09024f67bd71ec094b110237dc3840 upstream.
+
+In the following commit:
+
+  ce0fa3e56ad2 ("x86/mm, mm/hwpoison: Clear PRESENT bit for kernel 1:1 mappings of poison pages")
+
+... we added code to memory_failure() to unmap the page from the
+kernel 1:1 virtual address space to avoid speculative access to the
+page logging additional errors.
+
+But memory_failure() may not always succeed in taking the page offline,
+especially if the page belongs to the kernel.  This can happen if
+there are too many corrected errors on a page and either mcelog(8)
+or drivers/ras/cec.c asks to take a page offline.
+
+Since we remove the 1:1 mapping early in memory_failure(), we can
+end up with the page unmapped, but still in use. On the next access
+the kernel crashes :-(
+
+There are also various debug paths that call memory_failure() to simulate
+occurrence of an error. Since there is no actual error in memory, we
+don't need to map out the page for those cases.
+
+Revert most of the previous attempt and keep the solution local to
+arch/x86/kernel/cpu/mcheck/mce.c. Unmap the page only when:
+
+       1) there is a real error
+       2) memory_failure() succeeds.
+
+All of this only applies to 64-bit systems. 32-bit kernel doesn't map
+all of memory into kernel space. It isn't worth adding the code to unmap
+the piece that is mapped because nobody would run a 32-bit kernel on a
+machine that has recoverable machine checks.
+
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Borislav Petkov <bp@suse.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Dave <dave.hansen@intel.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Robert (Persistent Memory) <elliott@hpe.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-mm@kvack.org
+Cc: stable@vger.kernel.org #v4.14
+Fixes: ce0fa3e56ad2 ("x86/mm, mm/hwpoison: Clear PRESENT bit for kernel 1:1 mappings of poison pages")
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/page_64.h            |    4 ----
+ arch/x86/kernel/cpu/mcheck/mce-internal.h |   15 +++++++++++++++
+ arch/x86/kernel/cpu/mcheck/mce.c          |   17 +++++++++++------
+ include/linux/mm_inline.h                 |    6 ------
+ mm/memory-failure.c                       |    2 --
+ 5 files changed, 26 insertions(+), 18 deletions(-)
+
+--- a/arch/x86/include/asm/page_64.h
++++ b/arch/x86/include/asm/page_64.h
+@@ -52,10 +52,6 @@ static inline void clear_page(void *page
+ void copy_page(void *to, void *from);
+-#ifdef CONFIG_X86_MCE
+-#define arch_unmap_kpfn arch_unmap_kpfn
+-#endif
+-
+ #endif        /* !__ASSEMBLY__ */
+ #ifdef CONFIG_X86_VSYSCALL_EMULATION
+--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h
++++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h
+@@ -115,4 +115,19 @@ static inline void mce_unregister_inject
+ extern struct mca_config mca_cfg;
++#ifndef CONFIG_X86_64
++/*
++ * On 32-bit systems it would be difficult to safely unmap a poison page
++ * from the kernel 1:1 map because there are no non-canonical addresses that
++ * we can use to refer to the address without risking a speculative access.
++ * However, this isn't much of an issue because:
++ * 1) Few unmappable pages are in the 1:1 map. Most are in HIGHMEM which
++ *    are only mapped into the kernel as needed
++ * 2) Few people would run a 32-bit kernel on a machine that supports
++ *    recoverable errors because they have too much memory to boot 32-bit.
++ */
++static inline void mce_unmap_kpfn(unsigned long pfn) {}
++#define mce_unmap_kpfn mce_unmap_kpfn
++#endif
++
+ #endif /* __X86_MCE_INTERNAL_H__ */
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -106,6 +106,10 @@ static struct irq_work mce_irq_work;
+ static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
++#ifndef mce_unmap_kpfn
++static void mce_unmap_kpfn(unsigned long pfn);
++#endif
++
+ /*
+  * CPU/chipset specific EDAC code can register a notifier call here to print
+  * MCE errors in a human-readable form.
+@@ -582,7 +586,8 @@ static int srao_decode_notifier(struct n
+       if (mce_usable_address(mce) && (mce->severity == MCE_AO_SEVERITY)) {
+               pfn = mce->addr >> PAGE_SHIFT;
+-              memory_failure(pfn, MCE_VECTOR, 0);
++              if (memory_failure(pfn, MCE_VECTOR, 0))
++                      mce_unmap_kpfn(pfn);
+       }
+       return NOTIFY_OK;
+@@ -1049,12 +1054,13 @@ static int do_memory_failure(struct mce
+       ret = memory_failure(m->addr >> PAGE_SHIFT, MCE_VECTOR, flags);
+       if (ret)
+               pr_err("Memory error not recovered");
++      else
++              mce_unmap_kpfn(m->addr >> PAGE_SHIFT);
+       return ret;
+ }
+-#if defined(arch_unmap_kpfn) && defined(CONFIG_MEMORY_FAILURE)
+-
+-void arch_unmap_kpfn(unsigned long pfn)
++#ifndef mce_unmap_kpfn
++static void mce_unmap_kpfn(unsigned long pfn)
+ {
+       unsigned long decoy_addr;
+@@ -1065,7 +1071,7 @@ void arch_unmap_kpfn(unsigned long pfn)
+        * We would like to just call:
+        *      set_memory_np((unsigned long)pfn_to_kaddr(pfn), 1);
+        * but doing that would radically increase the odds of a
+-       * speculative access to the posion page because we'd have
++       * speculative access to the poison page because we'd have
+        * the virtual address of the kernel 1:1 mapping sitting
+        * around in registers.
+        * Instead we get tricky.  We create a non-canonical address
+@@ -1090,7 +1096,6 @@ void arch_unmap_kpfn(unsigned long pfn)
+       if (set_memory_np(decoy_addr, 1))
+               pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn);
+-
+ }
+ #endif
+--- a/include/linux/mm_inline.h
++++ b/include/linux/mm_inline.h
+@@ -127,10 +127,4 @@ static __always_inline enum lru_list pag
+ #define lru_to_page(head) (list_entry((head)->prev, struct page, lru))
+-#ifdef arch_unmap_kpfn
+-extern void arch_unmap_kpfn(unsigned long pfn);
+-#else
+-static __always_inline void arch_unmap_kpfn(unsigned long pfn) { }
+-#endif
+-
+ #endif
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1146,8 +1146,6 @@ int memory_failure(unsigned long pfn, in
+               return 0;
+       }
+-      arch_unmap_kpfn(pfn);
+-
+       orig_head = hpage = compound_head(p);
+       num_poisoned_pages_inc();
index 63a51c35b62f3b249b224efc7078a4bc46a2ca19..14efee8f26c7d42c538bdca1a6fd9e5093c5be4d 100644 (file)
@@ -42,6 +42,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  arch/x86/include/asm/paravirt_types.h |    2 +-
  arch/x86/include/asm/pgtable_32.h     |    2 +-
  arch/x86/include/asm/tlbflush.h       |   27 ++++++++++++++++++++-------
+ arch/x86/kernel/acpi/apei.c           |    2 +-
  arch/x86/kernel/paravirt.c            |    6 +++---
  arch/x86/mm/init_64.c                 |    2 +-
  arch/x86/mm/ioremap.c                 |    2 +-
@@ -51,7 +52,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  arch/x86/platform/uv/tlb_uv.c         |    2 +-
  arch/x86/xen/mmu_pv.c                 |    6 +++---
  include/trace/events/xen.h            |    2 +-
- 13 files changed, 39 insertions(+), 26 deletions(-)
+ 14 files changed, 40 insertions(+), 27 deletions(-)
 
 --- a/arch/x86/include/asm/paravirt.h
 +++ b/arch/x86/include/asm/paravirt.h
@@ -146,6 +147,15 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
         */
        invalidate_other_asid();
  }
+--- a/arch/x86/kernel/acpi/apei.c
++++ b/arch/x86/kernel/acpi/apei.c
+@@ -55,5 +55,5 @@ void arch_apei_report_mem_error(int sev,
+ void arch_apei_flush_tlb_one(unsigned long addr)
+ {
+-      __flush_tlb_one(addr);
++      __flush_tlb_one_kernel(addr);
+ }
 --- a/arch/x86/kernel/paravirt.c
 +++ b/arch/x86/kernel/paravirt.c
 @@ -190,9 +190,9 @@ static void native_flush_tlb_global(void