From: Sasha Levin Date: Fri, 5 Jul 2019 14:07:43 +0000 (-0400) Subject: fixes for 5.1 X-Git-Tag: v5.1.17~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12ae6b781ed2237f06a3f4b82df0dd7528d5358a;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.1 Signed-off-by: Sasha Levin --- diff --git a/queue-5.1/ftrace-x86-remove-possible-deadlock-between-register.patch b/queue-5.1/ftrace-x86-remove-possible-deadlock-between-register.patch new file mode 100644 index 00000000000..004ccb93b9f --- /dev/null +++ b/queue-5.1/ftrace-x86-remove-possible-deadlock-between-register.patch @@ -0,0 +1,189 @@ +From ec581b3fd5576fce9d4af96f937079ed695341ac Mon Sep 17 00:00:00 2001 +From: Petr Mladek +Date: Thu, 27 Jun 2019 10:13:34 +0200 +Subject: ftrace/x86: Remove possible deadlock between register_kprobe() and + ftrace_run_update_code() + +[ Upstream commit d5b844a2cf507fc7642c9ae80a9d585db3065c28 ] + +The commit 9f255b632bf12c4dd7 ("module: Fix livepatch/ftrace module text +permissions race") causes a possible deadlock between register_kprobe() +and ftrace_run_update_code() when ftrace is using stop_machine(). + +The existing dependency chain (in reverse order) is: + +-> #1 (text_mutex){+.+.}: + validate_chain.isra.21+0xb32/0xd70 + __lock_acquire+0x4b8/0x928 + lock_acquire+0x102/0x230 + __mutex_lock+0x88/0x908 + mutex_lock_nested+0x32/0x40 + register_kprobe+0x254/0x658 + init_kprobes+0x11a/0x168 + do_one_initcall+0x70/0x318 + kernel_init_freeable+0x456/0x508 + kernel_init+0x22/0x150 + ret_from_fork+0x30/0x34 + kernel_thread_starter+0x0/0xc + +-> #0 (cpu_hotplug_lock.rw_sem){++++}: + check_prev_add+0x90c/0xde0 + validate_chain.isra.21+0xb32/0xd70 + __lock_acquire+0x4b8/0x928 + lock_acquire+0x102/0x230 + cpus_read_lock+0x62/0xd0 + stop_machine+0x2e/0x60 + arch_ftrace_update_code+0x2e/0x40 + ftrace_run_update_code+0x40/0xa0 + ftrace_startup+0xb2/0x168 + register_ftrace_function+0x64/0x88 + klp_patch_object+0x1a2/0x290 + klp_enable_patch+0x554/0x980 + do_one_initcall+0x70/0x318 + do_init_module+0x6e/0x250 + load_module+0x1782/0x1990 + __s390x_sys_finit_module+0xaa/0xf0 + system_call+0xd8/0x2d0 + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(text_mutex); + lock(cpu_hotplug_lock.rw_sem); + lock(text_mutex); + lock(cpu_hotplug_lock.rw_sem); + +It is similar problem that has been solved by the commit 2d1e38f56622b9b +("kprobes: Cure hotplug lock ordering issues"). Many locks are involved. +To be on the safe side, text_mutex must become a low level lock taken +after cpu_hotplug_lock.rw_sem. + +This can't be achieved easily with the current ftrace design. +For example, arm calls set_all_modules_text_rw() already in +ftrace_arch_code_modify_prepare(), see arch/arm/kernel/ftrace.c. +This functions is called: + + + outside stop_machine() from ftrace_run_update_code() + + without stop_machine() from ftrace_module_enable() + +Fortunately, the problematic fix is needed only on x86_64. It is +the only architecture that calls set_all_modules_text_rw() +in ftrace path and supports livepatching at the same time. + +Therefore it is enough to move text_mutex handling from the generic +kernel/trace/ftrace.c into arch/x86/kernel/ftrace.c: + + ftrace_arch_code_modify_prepare() + ftrace_arch_code_modify_post_process() + +This patch basically reverts the ftrace part of the problematic +commit 9f255b632bf12c4dd7 ("module: Fix livepatch/ftrace module +text permissions race"). And provides x86_64 specific-fix. + +Some refactoring of the ftrace code will be needed when livepatching +is implemented for arm or nds32. These architectures call +set_all_modules_text_rw() and use stop_machine() at the same time. + +Link: http://lkml.kernel.org/r/20190627081334.12793-1-pmladek@suse.com + +Fixes: 9f255b632bf12c4dd7 ("module: Fix livepatch/ftrace module text permissions race") +Acked-by: Thomas Gleixner +Reported-by: Miroslav Benes +Reviewed-by: Miroslav Benes +Reviewed-by: Josh Poimboeuf +Signed-off-by: Petr Mladek +[ + As reviewed by Miroslav Benes , removed return value of + ftrace_run_update_code() as it is a void function. +] +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/ftrace.c | 3 +++ + kernel/trace/ftrace.c | 10 +--------- + 2 files changed, 4 insertions(+), 9 deletions(-) + +diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c +index 6e0c0ed8e4bf..ba3656405fcc 100644 +--- a/arch/x86/kernel/ftrace.c ++++ b/arch/x86/kernel/ftrace.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #include + +@@ -35,6 +36,7 @@ + + int ftrace_arch_code_modify_prepare(void) + { ++ mutex_lock(&text_mutex); + set_kernel_text_rw(); + set_all_modules_text_rw(); + return 0; +@@ -44,6 +46,7 @@ int ftrace_arch_code_modify_post_process(void) + { + set_all_modules_text_ro(); + set_kernel_text_ro(); ++ mutex_unlock(&text_mutex); + return 0; + } + +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 2469d54b3e43..6b6fa18f0a02 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -34,7 +34,6 @@ + #include + #include + #include +-#include + + #include + +@@ -2615,12 +2614,10 @@ static void ftrace_run_update_code(int command) + { + int ret; + +- mutex_lock(&text_mutex); +- + ret = ftrace_arch_code_modify_prepare(); + FTRACE_WARN_ON(ret); + if (ret) +- goto out_unlock; ++ return; + + /* + * By default we use stop_machine() to modify the code. +@@ -2632,9 +2629,6 @@ static void ftrace_run_update_code(int command) + + ret = ftrace_arch_code_modify_post_process(); + FTRACE_WARN_ON(ret); +- +-out_unlock: +- mutex_unlock(&text_mutex); + } + + static void ftrace_run_modify_code(struct ftrace_ops *ops, int command, +@@ -5788,7 +5782,6 @@ void ftrace_module_enable(struct module *mod) + struct ftrace_page *pg; + + mutex_lock(&ftrace_lock); +- mutex_lock(&text_mutex); + + if (ftrace_disabled) + goto out_unlock; +@@ -5850,7 +5843,6 @@ void ftrace_module_enable(struct module *mod) + ftrace_arch_code_modify_post_process(); + + out_unlock: +- mutex_unlock(&text_mutex); + mutex_unlock(&ftrace_lock); + + process_cached_mods(mod->name); +-- +2.20.1 + diff --git a/queue-5.1/s390-mm-fix-pxd_bad-with-folded-page-tables.patch b/queue-5.1/s390-mm-fix-pxd_bad-with-folded-page-tables.patch new file mode 100644 index 00000000000..db7704355d7 --- /dev/null +++ b/queue-5.1/s390-mm-fix-pxd_bad-with-folded-page-tables.patch @@ -0,0 +1,111 @@ +From bfea22e3bc8d2f9006ee9cd38ad0a8573bd42324 Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Wed, 24 Apr 2019 12:49:44 +0200 +Subject: s390/mm: fix pxd_bad with folded page tables + +[ Upstream commit c9f621524e70774688db3cec60d85fa4c7de52e3 ] + +With git commit d1874a0c2805fcfa9162c972d6b7541e57adb542 +"s390/mm: make the pxd_offset functions more robust" and a 2-level page +table it can now happen that pgd_bad() gets asked to verify a large +segment table entry. If the entry is marked as dirty pgd_bad() will +incorrectly return true. + +Change the pgd_bad(), p4d_bad(), pud_bad() and pmd_bad() functions to +first verify the table type, return false if the table level is lower +than what the function is suppossed to check, return true if the table +level is too high, and otherwise check the relevant region and segment +table bits. pmd_bad() has to check against ~SEGMENT_ENTRY_BITS for +normal page table pointers or ~SEGMENT_ENTRY_BITS_LARGE for large +segment table entries. Same for pud_bad() which has to check against +~_REGION_ENTRY_BITS or ~_REGION_ENTRY_BITS_LARGE. + +Fixes: d1874a0c2805 ("s390/mm: make the pxd_offset functions more robust") +Signed-off-by: Martin Schwidefsky +Signed-off-by: Sasha Levin +--- + arch/s390/include/asm/pgtable.h | 33 +++++++++++++++++++-------------- + 1 file changed, 19 insertions(+), 14 deletions(-) + +diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h +index 394bec31cb97..9f0195d5fa16 100644 +--- a/arch/s390/include/asm/pgtable.h ++++ b/arch/s390/include/asm/pgtable.h +@@ -238,7 +238,7 @@ static inline int is_module_addr(void *addr) + #define _REGION_ENTRY_NOEXEC 0x100 /* region no-execute bit */ + #define _REGION_ENTRY_OFFSET 0xc0 /* region table offset */ + #define _REGION_ENTRY_INVALID 0x20 /* invalid region table entry */ +-#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ ++#define _REGION_ENTRY_TYPE_MASK 0x0c /* region table type mask */ + #define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ + #define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ + #define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */ +@@ -277,6 +277,7 @@ static inline int is_module_addr(void *addr) + #define _SEGMENT_ENTRY_PROTECT 0x200 /* segment protection bit */ + #define _SEGMENT_ENTRY_NOEXEC 0x100 /* segment no-execute bit */ + #define _SEGMENT_ENTRY_INVALID 0x20 /* invalid segment table entry */ ++#define _SEGMENT_ENTRY_TYPE_MASK 0x0c /* segment table type mask */ + + #define _SEGMENT_ENTRY (0) + #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INVALID) +@@ -614,15 +615,9 @@ static inline int pgd_none(pgd_t pgd) + + static inline int pgd_bad(pgd_t pgd) + { +- /* +- * With dynamic page table levels the pgd can be a region table +- * entry or a segment table entry. Check for the bit that are +- * invalid for either table entry. +- */ +- unsigned long mask = +- ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INVALID & +- ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; +- return (pgd_val(pgd) & mask) != 0; ++ if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R1) ++ return 0; ++ return (pgd_val(pgd) & ~_REGION_ENTRY_BITS) != 0; + } + + static inline unsigned long pgd_pfn(pgd_t pgd) +@@ -703,6 +698,8 @@ static inline int pmd_large(pmd_t pmd) + + static inline int pmd_bad(pmd_t pmd) + { ++ if ((pmd_val(pmd) & _SEGMENT_ENTRY_TYPE_MASK) > 0) ++ return 1; + if (pmd_large(pmd)) + return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS_LARGE) != 0; + return (pmd_val(pmd) & ~_SEGMENT_ENTRY_BITS) != 0; +@@ -710,8 +707,12 @@ static inline int pmd_bad(pmd_t pmd) + + static inline int pud_bad(pud_t pud) + { +- if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) +- return pmd_bad(__pmd(pud_val(pud))); ++ unsigned long type = pud_val(pud) & _REGION_ENTRY_TYPE_MASK; ++ ++ if (type > _REGION_ENTRY_TYPE_R3) ++ return 1; ++ if (type < _REGION_ENTRY_TYPE_R3) ++ return 0; + if (pud_large(pud)) + return (pud_val(pud) & ~_REGION_ENTRY_BITS_LARGE) != 0; + return (pud_val(pud) & ~_REGION_ENTRY_BITS) != 0; +@@ -719,8 +720,12 @@ static inline int pud_bad(pud_t pud) + + static inline int p4d_bad(p4d_t p4d) + { +- if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) +- return pud_bad(__pud(p4d_val(p4d))); ++ unsigned long type = p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK; ++ ++ if (type > _REGION_ENTRY_TYPE_R2) ++ return 1; ++ if (type < _REGION_ENTRY_TYPE_R2) ++ return 0; + return (p4d_val(p4d) & ~_REGION_ENTRY_BITS) != 0; + } + +-- +2.20.1 + diff --git a/queue-5.1/series b/queue-5.1/series index d409e6d628f..2f625132275 100644 --- a/queue-5.1/series +++ b/queue-5.1/series @@ -80,3 +80,6 @@ drm-imx-only-send-event-on-crtc-disable-if-kept-disabled.patch ftrace-x86-remove-possible-deadlock-between-register_kprobe-and-ftrace_run_update_code.patch mm-vmscan.c-prevent-useless-kswapd-loops.patch btrfs-ensure-replaced-device-doesn-t-have-pending-chunk-allocation.patch +tty-rocket-fix-incorrect-forward-declaration-of-rp_i.patch +ftrace-x86-remove-possible-deadlock-between-register.patch +s390-mm-fix-pxd_bad-with-folded-page-tables.patch diff --git a/queue-5.1/tty-rocket-fix-incorrect-forward-declaration-of-rp_i.patch b/queue-5.1/tty-rocket-fix-incorrect-forward-declaration-of-rp_i.patch new file mode 100644 index 00000000000..06d1975e167 --- /dev/null +++ b/queue-5.1/tty-rocket-fix-incorrect-forward-declaration-of-rp_i.patch @@ -0,0 +1,36 @@ +From 3413ec359caba023694a64f84ddcb1bbf9db3f80 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Mon, 6 May 2019 11:28:23 -0700 +Subject: tty: rocket: fix incorrect forward declaration of 'rp_init()' + +[ Upstream commit 423ea3255424b954947d167681b71ded1b8fca53 ] + +Make the forward declaration actually match the real function +definition, something that previous versions of gcc had just ignored. + +This is another patch to fix new warnings from gcc-9 before I start the +merge window pulls. I don't want to miss legitimate new warnings just +because my system update brought a new compiler with new warnings. + +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +--- + drivers/tty/rocket.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c +index b121d8f8f3d7..27aeca30eeae 100644 +--- a/drivers/tty/rocket.c ++++ b/drivers/tty/rocket.c +@@ -266,7 +266,7 @@ MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc1 + module_param_array(pc104_4, ulong, NULL, 0); + MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,..."); + +-static int rp_init(void); ++static int __init rp_init(void); + static void rp_cleanup_module(void); + + module_init(rp_init); +-- +2.20.1 +