]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 5.1
authorSasha Levin <sashal@kernel.org>
Fri, 5 Jul 2019 14:07:43 +0000 (10:07 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 5 Jul 2019 14:07:43 +0000 (10:07 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.1/ftrace-x86-remove-possible-deadlock-between-register.patch [new file with mode: 0644]
queue-5.1/s390-mm-fix-pxd_bad-with-folded-page-tables.patch [new file with mode: 0644]
queue-5.1/series
queue-5.1/tty-rocket-fix-incorrect-forward-declaration-of-rp_i.patch [new file with mode: 0644]

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 (file)
index 0000000..004ccb9
--- /dev/null
@@ -0,0 +1,189 @@
+From ec581b3fd5576fce9d4af96f937079ed695341ac Mon Sep 17 00:00:00 2001
+From: Petr Mladek <pmladek@suse.com>
+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 <tglx@linutronix.de>
+Reported-by: Miroslav Benes <mbenes@suse.cz>
+Reviewed-by: Miroslav Benes <mbenes@suse.cz>
+Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Signed-off-by: Petr Mladek <pmladek@suse.com>
+[
+  As reviewed by Miroslav Benes <mbenes@suse.cz>, removed return value of
+  ftrace_run_update_code() as it is a void function.
+]
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <linux/init.h>
+ #include <linux/list.h>
+ #include <linux/module.h>
++#include <linux/memory.h>
+ #include <trace/syscall.h>
+@@ -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 <linux/hash.h>
+ #include <linux/rcupdate.h>
+ #include <linux/kprobes.h>
+-#include <linux/memory.h>
+ #include <trace/events/sched.h>
+@@ -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 (file)
index 0000000..db77043
--- /dev/null
@@ -0,0 +1,111 @@
+From bfea22e3bc8d2f9006ee9cd38ad0a8573bd42324 Mon Sep 17 00:00:00 2001
+From: Martin Schwidefsky <schwidefsky@de.ibm.com>
+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 <schwidefsky@de.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index d409e6d628f5fc3c065fb34819ffafee7aaca2c6..2f6251322758e55349d1650dacab525829761d93 100644 (file)
@@ -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 (file)
index 0000000..06d1975
--- /dev/null
@@ -0,0 +1,36 @@
+From 3413ec359caba023694a64f84ddcb1bbf9db3f80 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+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 <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+