summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2019-04-08 12:56:34 -0400
committerWill Deacon <will.deacon@arm.com>2019-04-08 13:05:24 -0400
commit1e6f5440a6814d28c32d347f338bfef68bc3e69d (patch)
tree4010520c549266a7637d2587f0a541355da026b2
parent5a3ae7b314a2259b1188b22b392f5eba01e443ee (diff)
arm64: backtrace: Don't bother trying to unwind the userspace stack
Calling dump_backtrace() with a pt_regs argument corresponding to userspace doesn't make any sense and our unwinder will simply print "Call trace:" before unwinding the stack looking for user frames. Rather than go through this song and dance, just return early if we're passed a user register state. Cc: <stable@vger.kernel.org> Fixes: 1149aad10b1e ("arm64: Add dump_backtrace() in show_regs") Reported-by: Kefeng Wang <wangkefeng.wang@huawei.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/kernel/traps.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 8ad119c3f665..29755989f616 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -102,10 +102,16 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
102void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) 102void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
103{ 103{
104 struct stackframe frame; 104 struct stackframe frame;
105 int skip; 105 int skip = 0;
106 106
107 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); 107 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
108 108
109 if (regs) {
110 if (user_mode(regs))
111 return;
112 skip = 1;
113 }
114
109 if (!tsk) 115 if (!tsk)
110 tsk = current; 116 tsk = current;
111 117
@@ -126,7 +132,6 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
126 frame.graph = 0; 132 frame.graph = 0;
127#endif 133#endif
128 134
129 skip = !!regs;
130 printk("Call trace:\n"); 135 printk("Call trace:\n");
131 do { 136 do {
132 /* skip until specified stack frame */ 137 /* skip until specified stack frame */
@@ -176,15 +181,13 @@ static int __die(const char *str, int err, struct pt_regs *regs)
176 return ret; 181 return ret;
177 182
178 print_modules(); 183 print_modules();
179 __show_regs(regs);
180 pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n", 184 pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
181 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), 185 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk),
182 end_of_stack(tsk)); 186 end_of_stack(tsk));
187 show_regs(regs);
183 188
184 if (!user_mode(regs)) { 189 if (!user_mode(regs))
185 dump_backtrace(regs, tsk);
186 dump_instr(KERN_EMERG, regs); 190 dump_instr(KERN_EMERG, regs);
187 }
188 191
189 return ret; 192 return ret;
190} 193}