summaryrefslogtreecommitdiffstats
path: root/arch/arc
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2018-12-18 10:39:58 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-16 08:22:02 +0200
commit96af7d92d8d27d97edc65ce53d8dd8c4d0f4fa58 (patch)
tree613003c99a2b6622c4874d750e16973a40d2cdae /arch/arc
parent424b75b79994c57a87e34ff1a0fd462dd3dbcb24 (diff)
downloadlinux-stable-96af7d92d8d27d97edc65ce53d8dd8c4d0f4fa58.tar.gz
linux-stable-96af7d92d8d27d97edc65ce53d8dd8c4d0f4fa58.tar.bz2
linux-stable-96af7d92d8d27d97edc65ce53d8dd8c4d0f4fa58.zip
ARC: show_regs: lockdep: re-enable preemption
[ Upstream commit f731a8e89f8c78985707c626680f3e24c7a60772 ] signal handling core calls show_regs() with preemption disabled which on ARC takes mmap_sem for mm/vma access, causing lockdep splat. | [ARCLinux]# ./segv-null-ptr | potentially unexpected fatal signal 11. | BUG: sleeping function called from invalid context at kernel/fork.c:1011 | in_atomic(): 1, irqs_disabled(): 0, pid: 70, name: segv-null-ptr | no locks held by segv-null-ptr/70. | CPU: 0 PID: 70 Comm: segv-null-ptr Not tainted 4.18.0+ #69 | | Stack Trace: | arc_unwind_core+0xcc/0x100 | ___might_sleep+0x17a/0x190 | mmput+0x16/0xb8 | show_regs+0x52/0x310 | get_signal+0x5ee/0x610 | do_signal+0x2c/0x218 | resume_user_mode_begin+0x90/0xd8 Workaround by re-enabling preemption temporarily. Note that the preemption disabling in core code around show_regs() was introduced by commit 3a9f84d354ce ("signals, debug: fix BUG: using smp_processor_id() in preemptible code in print_fatal_signal()") to silence a differnt lockdep seen on x86 bakc in 2009. Cc: <stable@vger.kernel.org> Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'arch/arc')
-rw-r--r--arch/arc/kernel/troubleshoot.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index 5c6663321e87..215f515442e0 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -179,6 +179,12 @@ void show_regs(struct pt_regs *regs)
struct task_struct *tsk = current;
struct callee_regs *cregs;
+ /*
+ * generic code calls us with preemption disabled, but some calls
+ * here could sleep, so re-enable to avoid lockdep splat
+ */
+ preempt_enable();
+
print_task_path_n_nm(tsk);
show_regs_print_info(KERN_INFO);
@@ -221,6 +227,8 @@ void show_regs(struct pt_regs *regs)
cregs = (struct callee_regs *)current->thread.callee_reg;
if (cregs)
show_callee_regs(cregs);
+
+ preempt_disable();
}
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,