From: Greg Kroah-Hartman Date: Mon, 17 Jun 2019 12:53:48 +0000 (+0200) Subject: 5.1-stable patches X-Git-Tag: v5.1.11~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5478867b9ad03a41e886b0d5506752b4f1b69d30;p=thirdparty%2Fkernel%2Fstable-queue.git 5.1-stable patches added patches: powerpc-64s-fix-thp-pmd-collapse-serialisation.patch powerpc-fix-kexec-failure-on-book3s-32.patch --- diff --git a/queue-5.1/powerpc-64s-fix-thp-pmd-collapse-serialisation.patch b/queue-5.1/powerpc-64s-fix-thp-pmd-collapse-serialisation.patch new file mode 100644 index 00000000000..f165c268c49 --- /dev/null +++ b/queue-5.1/powerpc-64s-fix-thp-pmd-collapse-serialisation.patch @@ -0,0 +1,102 @@ +From 33258a1db165cf43a9e6382587ad06e9b7f8187c Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Fri, 7 Jun 2019 13:56:35 +1000 +Subject: powerpc/64s: Fix THP PMD collapse serialisation + +From: Nicholas Piggin + +commit 33258a1db165cf43a9e6382587ad06e9b7f8187c upstream. + +Commit 1b2443a547f9 ("powerpc/book3s64: Avoid multiple endian +conversion in pte helpers") changed the actual bitwise tests in +pte_access_permitted by using pte_write() and pte_present() helpers +rather than raw bitwise testing _PAGE_WRITE and _PAGE_PRESENT bits. + +The pte_present() change now returns true for PTEs which are +!_PAGE_PRESENT and _PAGE_INVALID, which is the combination used by +pmdp_invalidate() to synchronize access from lock-free lookups. +pte_access_permitted() is used by pmd_access_permitted(), so allowing +GUP lock free access to proceed with such PTEs breaks this +synchronisation. + +This bug has been observed on a host using the hash page table MMU, +with random crashes and corruption in guests, usually together with +bad PMD messages in the host. + +Fix this by adding an explicit check in pmd_access_permitted(), and +documenting the condition explicitly. + +The pte_write() change should be okay, and would prevent GUP from +falling back to the slow path when encountering savedwrite PTEs, which +matches what x86 (that does not implement savedwrite) does. + +Fixes: 1b2443a547f9 ("powerpc/book3s64: Avoid multiple endian conversion in pte helpers") +Cc: stable@vger.kernel.org # v4.20+ +Signed-off-by: Nicholas Piggin +Reviewed-by: Aneesh Kumar K.V +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/book3s/64/pgtable.h | 30 +++++++++++++++++++++++++++ + arch/powerpc/mm/pgtable-book3s64.c | 3 ++ + 2 files changed, 33 insertions(+) + +--- a/arch/powerpc/include/asm/book3s/64/pgtable.h ++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h +@@ -875,6 +875,23 @@ static inline int pmd_present(pmd_t pmd) + return false; + } + ++static inline int pmd_is_serializing(pmd_t pmd) ++{ ++ /* ++ * If the pmd is undergoing a split, the _PAGE_PRESENT bit is clear ++ * and _PAGE_INVALID is set (see pmd_present, pmdp_invalidate). ++ * ++ * This condition may also occur when flushing a pmd while flushing ++ * it (see ptep_modify_prot_start), so callers must ensure this ++ * case is fine as well. ++ */ ++ if ((pmd_raw(pmd) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID)) == ++ cpu_to_be64(_PAGE_INVALID)) ++ return true; ++ ++ return false; ++} ++ + static inline int pmd_bad(pmd_t pmd) + { + if (radix_enabled()) +@@ -1090,6 +1107,19 @@ static inline int pmd_protnone(pmd_t pmd + #define pmd_access_permitted pmd_access_permitted + static inline bool pmd_access_permitted(pmd_t pmd, bool write) + { ++ /* ++ * pmdp_invalidate sets this combination (which is not caught by ++ * !pte_present() check in pte_access_permitted), to prevent ++ * lock-free lookups, as part of the serialize_against_pte_lookup() ++ * synchronisation. ++ * ++ * This also catches the case where the PTE's hardware PRESENT bit is ++ * cleared while TLB is flushed, which is suboptimal but should not ++ * be frequent. ++ */ ++ if (pmd_is_serializing(pmd)) ++ return false; ++ + return pte_access_permitted(pmd_pte(pmd), write); + } + +--- a/arch/powerpc/mm/pgtable-book3s64.c ++++ b/arch/powerpc/mm/pgtable-book3s64.c +@@ -116,6 +116,9 @@ pmd_t pmdp_invalidate(struct vm_area_str + /* + * This ensures that generic code that rely on IRQ disabling + * to prevent a parallel THP split work as expected. ++ * ++ * Marking the entry with _PAGE_INVALID && ~_PAGE_PRESENT requires ++ * a special case check in pmd_access_permitted. + */ + serialize_against_pte_lookup(vma->vm_mm); + return __pmd(old_pmd); diff --git a/queue-5.1/powerpc-fix-kexec-failure-on-book3s-32.patch b/queue-5.1/powerpc-fix-kexec-failure-on-book3s-32.patch new file mode 100644 index 00000000000..3a9ac5dfa55 --- /dev/null +++ b/queue-5.1/powerpc-fix-kexec-failure-on-book3s-32.patch @@ -0,0 +1,79 @@ +From 6c284228eb356a1ec62a704b4d2329711831eaed Mon Sep 17 00:00:00 2001 +From: Christophe Leroy +Date: Mon, 3 Jun 2019 08:20:28 +0000 +Subject: powerpc: Fix kexec failure on book3s/32 + +From: Christophe Leroy + +commit 6c284228eb356a1ec62a704b4d2329711831eaed upstream. + +In the old days, _PAGE_EXEC didn't exist on 6xx aka book3s/32. +Therefore, allthough __mapin_ram_chunk() was already mapping kernel +text with PAGE_KERNEL_TEXT and the rest with PAGE_KERNEL, the entire +memory was executable. Part of the memory (first 512kbytes) was +mapped with BATs instead of page table, but it was also entirely +mapped as executable. + +In commit 385e89d5b20f ("powerpc/mm: add exec protection on +powerpc 603"), we started adding exec protection to some 6xx, namely +the 603, for pages mapped via pagetables. + +Then, in commit 63b2bc619565 ("powerpc/mm/32s: Use BATs for +STRICT_KERNEL_RWX"), the exec protection was extended to BAT mapped +memory, so that really only the kernel text could be executed. + +The problem here is that kexec is based on copying some code into +upper part of memory then executing it from there in order to install +a fresh new kernel at its definitive location. + +However, the code is position independant and first part of it is +just there to deactivate the MMU and jump to the second part. So it +is possible to run this first part inplace instead of running the +copy. Once the MMU is off, there is no protection anymore and the +second part of the code will just run as before. + +Reported-by: Aaro Koskinen +Fixes: 63b2bc619565 ("powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX") +Cc: stable@vger.kernel.org # v5.1+ +Signed-off-by: Christophe Leroy +Tested-by: Aaro Koskinen +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/kexec.h | 3 +++ + arch/powerpc/kernel/machine_kexec_32.c | 4 +++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/include/asm/kexec.h ++++ b/arch/powerpc/include/asm/kexec.h +@@ -94,6 +94,9 @@ static inline bool kdump_in_progress(voi + return crashing_cpu >= 0; + } + ++void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_code_buffer, ++ unsigned long start_address) __noreturn; ++ + #ifdef CONFIG_KEXEC_FILE + extern const struct kexec_file_ops kexec_elf64_ops; + +--- a/arch/powerpc/kernel/machine_kexec_32.c ++++ b/arch/powerpc/kernel/machine_kexec_32.c +@@ -30,7 +30,6 @@ typedef void (*relocate_new_kernel_t)( + */ + void default_machine_kexec(struct kimage *image) + { +- extern const unsigned char relocate_new_kernel[]; + extern const unsigned int relocate_new_kernel_size; + unsigned long page_list; + unsigned long reboot_code_buffer, reboot_code_buffer_phys; +@@ -58,6 +57,9 @@ void default_machine_kexec(struct kimage + reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); + printk(KERN_INFO "Bye!\n"); + ++ if (!IS_ENABLED(CONFIG_FSL_BOOKE) && !IS_ENABLED(CONFIG_44x)) ++ relocate_new_kernel(page_list, reboot_code_buffer_phys, image->start); ++ + /* now call it */ + rnk = (relocate_new_kernel_t) reboot_code_buffer; + (*rnk)(page_list, reboot_code_buffer_phys, image->start); diff --git a/queue-5.1/series b/queue-5.1/series index bc599bb2c1b..8a5b22507b4 100644 --- a/queue-5.1/series +++ b/queue-5.1/series @@ -111,3 +111,5 @@ x86-mm-kaslr-compute-the-size-of-the-vmemmap-section-properly.patch x86-resctrl-prevent-null-pointer-dereference-when-local-mbm-is-disabled.patch drm-edid-abstract-override-firmware-edid-retrieval.patch drm-add-fallback-override-firmware-edid-modes-workaround.patch +powerpc-fix-kexec-failure-on-book3s-32.patch +powerpc-64s-fix-thp-pmd-collapse-serialisation.patch