diff options
author | Helge Deller <deller@gmx.de> | 2018-08-17 11:00:08 -0400 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2018-08-17 11:00:08 -0400 |
commit | 9e0d5c451f9e559dd06af3fff49a0d2068c634c4 (patch) | |
tree | 1293c908104370c76548f0695297b0277835e1ec | |
parent | 54c770da992387abfa7df4817404d000ef034fa8 (diff) |
parisc: Consolidate unwind initialization calls
Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r-- | arch/parisc/include/asm/unwind.h | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/stacktrace.c | 15 | ||||
-rw-r--r-- | arch/parisc/kernel/traps.c | 35 | ||||
-rw-r--r-- | arch/parisc/kernel/unwind.c | 37 |
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 | ||
74 | void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, | 74 | void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, |
75 | struct pt_regs *regs); | 75 | struct pt_regs *regs); |
76 | void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t); | 76 | void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, |
77 | void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs); | 77 | struct task_struct *t); |
78 | void unwind_frame_init_task(struct unwind_frame_info *info, | ||
79 | struct task_struct *task, struct pt_regs *regs); | ||
78 | int unwind_once(struct unwind_frame_info *info); | 80 | int unwind_once(struct unwind_frame_info *info); |
79 | int unwind_to_user(struct unwind_frame_info *info); | 81 | int 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; | ||
23 | HERE: | ||
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 | ||
48 | static void parisc_show_stack(struct task_struct *task, unsigned long *sp, | 48 | static void parisc_show_stack(struct task_struct *task, |
49 | struct pt_regs *regs); | 49 | struct pt_regs *regs); |
50 | 50 | ||
51 | static int printbinary(char *buf, unsigned long x, int nbits) | 51 | static 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 | ||
188 | static void parisc_show_stack(struct task_struct *task, unsigned long *sp, | 188 | static 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 | |||
203 | HERE: | ||
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 | ||
219 | show_stack: | ||
220 | do_show_stack(&info); | 195 | do_show_stack(&info); |
221 | } | 196 | } |
222 | 197 | ||
223 | void show_stack(struct task_struct *t, unsigned long *sp) | 198 | void 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 | ||
228 | int is_valid_bugaddr(unsigned long iaoq) | 203 | int 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 | ||
406 | void 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 | |||
412 | void 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 | ||
411 | int unwind_once(struct unwind_frame_info *next_frame) | 433 | int unwind_once(struct unwind_frame_info *next_frame) |
@@ -442,19 +464,12 @@ int unwind_to_user(struct unwind_frame_info *info) | |||
442 | unsigned long return_address(unsigned int level) | 464 | unsigned 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; |