aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2018-08-17 11:00:08 -0400
committerHelge Deller <deller@gmx.de>2018-08-17 11:00:08 -0400
commit9e0d5c451f9e559dd06af3fff49a0d2068c634c4 (patch)
tree1293c908104370c76548f0695297b0277835e1ec
parent54c770da992387abfa7df4817404d000ef034fa8 (diff)
parisc: Consolidate unwind initialization calls
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--arch/parisc/include/asm/unwind.h6
-rw-r--r--arch/parisc/kernel/stacktrace.c15
-rw-r--r--arch/parisc/kernel/traps.c35
-rw-r--r--arch/parisc/kernel/unwind.c37
4 files changed, 36 insertions, 57 deletions
diff --git a/arch/parisc/include/asm/unwind.h b/arch/parisc/include/asm/unwind.h
index f133b7efbebb..9547e5261a8b 100644
--- a/arch/parisc/include/asm/unwind.h
+++ b/arch/parisc/include/asm/unwind.h
@@ -73,8 +73,10 @@ unwind_table_remove(struct unwind_table *table);
73 73
74void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, 74void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
75 struct pt_regs *regs); 75 struct pt_regs *regs);
76void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t); 76void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info,
77void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs); 77 struct task_struct *t);
78void unwind_frame_init_task(struct unwind_frame_info *info,
79 struct task_struct *task, struct pt_regs *regs);
78int unwind_once(struct unwind_frame_info *info); 80int unwind_once(struct unwind_frame_info *info);
79int unwind_to_user(struct unwind_frame_info *info); 81int unwind_to_user(struct unwind_frame_info *info);
80 82
diff --git a/arch/parisc/kernel/stacktrace.c b/arch/parisc/kernel/stacktrace.c
index 2fe914c5f533..ec5835e83a7a 100644
--- a/arch/parisc/kernel/stacktrace.c
+++ b/arch/parisc/kernel/stacktrace.c
@@ -16,20 +16,7 @@ static void dump_trace(struct task_struct *task, struct stack_trace *trace)
16{ 16{
17 struct unwind_frame_info info; 17 struct unwind_frame_info info;
18 18
19 /* initialize unwind info */ 19 unwind_frame_init_task(&info, task, NULL);
20 if (task == current) {
21 unsigned long sp;
22 struct pt_regs r;
23HERE:
24 asm volatile ("copy %%r30, %0" : "=r"(sp));
25 memset(&r, 0, sizeof(struct pt_regs));
26 r.iaoq[0] = (unsigned long)&&HERE;
27 r.gr[2] = (unsigned long)__builtin_return_address(0);
28 r.gr[30] = sp;
29 unwind_frame_init(&info, task, &r);
30 } else {
31 unwind_frame_init_from_blocked_task(&info, task);
32 }
33 20
34 /* unwind stack and save entries in stack_trace struct */ 21 /* unwind stack and save entries in stack_trace struct */
35 trace->nr_entries = 0; 22 trace->nr_entries = 0;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 9372a41c8812..68f10f87073d 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -45,7 +45,7 @@
45 45
46#include "../math-emu/math-emu.h" /* for handle_fpe() */ 46#include "../math-emu/math-emu.h" /* for handle_fpe() */
47 47
48static void parisc_show_stack(struct task_struct *task, unsigned long *sp, 48static void parisc_show_stack(struct task_struct *task,
49 struct pt_regs *regs); 49 struct pt_regs *regs);
50 50
51static int printbinary(char *buf, unsigned long x, int nbits) 51static int printbinary(char *buf, unsigned long x, int nbits)
@@ -152,7 +152,7 @@ void show_regs(struct pt_regs *regs)
152 printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]); 152 printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
153 printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]); 153 printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
154 154
155 parisc_show_stack(current, NULL, regs); 155 parisc_show_stack(current, regs);
156 } 156 }
157} 157}
158 158
@@ -185,44 +185,19 @@ static void do_show_stack(struct unwind_frame_info *info)
185 printk(KERN_CRIT "\n"); 185 printk(KERN_CRIT "\n");
186} 186}
187 187
188static void parisc_show_stack(struct task_struct *task, unsigned long *sp, 188static void parisc_show_stack(struct task_struct *task,
189 struct pt_regs *regs) 189 struct pt_regs *regs)
190{ 190{
191 struct unwind_frame_info info; 191 struct unwind_frame_info info;
192 struct task_struct *t;
193 192
194 t = task ? task : current; 193 unwind_frame_init_task(&info, task, regs);
195 if (regs) {
196 unwind_frame_init(&info, t, regs);
197 goto show_stack;
198 }
199
200 if (t == current) {
201 unsigned long sp;
202
203HERE:
204 asm volatile ("copy %%r30, %0" : "=r"(sp));
205 {
206 struct pt_regs r;
207
208 memset(&r, 0, sizeof(struct pt_regs));
209 r.iaoq[0] = (unsigned long)&&HERE;
210 r.gr[2] = (unsigned long)__builtin_return_address(0);
211 r.gr[30] = sp;
212
213 unwind_frame_init(&info, current, &r);
214 }
215 } else {
216 unwind_frame_init_from_blocked_task(&info, t);
217 }
218 194
219show_stack:
220 do_show_stack(&info); 195 do_show_stack(&info);
221} 196}
222 197
223void show_stack(struct task_struct *t, unsigned long *sp) 198void show_stack(struct task_struct *t, unsigned long *sp)
224{ 199{
225 return parisc_show_stack(t, sp, NULL); 200 parisc_show_stack(t, NULL);
226} 201}
227 202
228int is_valid_bugaddr(unsigned long iaoq) 203int is_valid_bugaddr(unsigned long iaoq)
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 5cdf13069dd9..5578a325a730 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -403,9 +403,31 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
403 kfree(r2); 403 kfree(r2);
404} 404}
405 405
406void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs) 406#define get_parisc_stackpointer() ({ \
407 unsigned long sp; \
408 __asm__("copy %%r30, %0" : "=r"(sp)); \
409 (sp); \
410})
411
412void unwind_frame_init_task(struct unwind_frame_info *info,
413 struct task_struct *task, struct pt_regs *regs)
407{ 414{
408 unwind_frame_init(info, current, regs); 415 task = task ? task : current;
416
417 if (task == current) {
418 struct pt_regs r;
419
420 if (!regs) {
421 memset(&r, 0, sizeof(r));
422 r.iaoq[0] = _THIS_IP_;
423 r.gr[2] = _RET_IP_;
424 r.gr[30] = get_parisc_stackpointer();
425 regs = &r;
426 }
427 unwind_frame_init(info, task, &r);
428 } else {
429 unwind_frame_init_from_blocked_task(info, task);
430 }
409} 431}
410 432
411int unwind_once(struct unwind_frame_info *next_frame) 433int unwind_once(struct unwind_frame_info *next_frame)
@@ -442,19 +464,12 @@ int unwind_to_user(struct unwind_frame_info *info)
442unsigned long return_address(unsigned int level) 464unsigned long return_address(unsigned int level)
443{ 465{
444 struct unwind_frame_info info; 466 struct unwind_frame_info info;
445 struct pt_regs r;
446 unsigned long sp;
447 467
448 /* initialize unwind info */ 468 /* initialize unwind info */
449 asm volatile ("copy %%r30, %0" : "=r"(sp)); 469 unwind_frame_init_task(&info, current, NULL);
450 memset(&r, 0, sizeof(struct pt_regs));
451 r.iaoq[0] = _THIS_IP_;
452 r.gr[2] = _RET_IP_;
453 r.gr[30] = sp;
454 unwind_frame_init(&info, current, &r);
455 470
456 /* unwind stack */ 471 /* unwind stack */
457 ++level; 472 level += 2;
458 do { 473 do {
459 if (unwind_once(&info) < 0 || info.ip == 0) 474 if (unwind_once(&info) < 0 || info.ip == 0)
460 return 0; 475 return 0;