Commit 9e0d5c45 authored by Helge Deller's avatar Helge Deller

parisc: Consolidate unwind initialization calls

Signed-off-by: default avatarHelge Deller <deller@gmx.de>
parent 54c770da
...@@ -73,8 +73,10 @@ unwind_table_remove(struct unwind_table *table); ...@@ -73,8 +73,10 @@ unwind_table_remove(struct unwind_table *table);
void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t, void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
struct pt_regs *regs); struct pt_regs *regs);
void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t); void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info,
void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs); struct task_struct *t);
void unwind_frame_init_task(struct unwind_frame_info *info,
struct task_struct *task, struct pt_regs *regs);
int unwind_once(struct unwind_frame_info *info); int unwind_once(struct unwind_frame_info *info);
int unwind_to_user(struct unwind_frame_info *info); int unwind_to_user(struct unwind_frame_info *info);
......
...@@ -16,20 +16,7 @@ static void dump_trace(struct task_struct *task, struct stack_trace *trace) ...@@ -16,20 +16,7 @@ static void dump_trace(struct task_struct *task, struct stack_trace *trace)
{ {
struct unwind_frame_info info; struct unwind_frame_info info;
/* initialize unwind info */ unwind_frame_init_task(&info, task, NULL);
if (task == current) {
unsigned long sp;
struct pt_regs r;
HERE:
asm volatile ("copy %%r30, %0" : "=r"(sp));
memset(&r, 0, sizeof(struct pt_regs));
r.iaoq[0] = (unsigned long)&&HERE;
r.gr[2] = (unsigned long)__builtin_return_address(0);
r.gr[30] = sp;
unwind_frame_init(&info, task, &r);
} else {
unwind_frame_init_from_blocked_task(&info, task);
}
/* unwind stack and save entries in stack_trace struct */ /* unwind stack and save entries in stack_trace struct */
trace->nr_entries = 0; trace->nr_entries = 0;
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
#include "../math-emu/math-emu.h" /* for handle_fpe() */ #include "../math-emu/math-emu.h" /* for handle_fpe() */
static void parisc_show_stack(struct task_struct *task, unsigned long *sp, static void parisc_show_stack(struct task_struct *task,
struct pt_regs *regs); struct pt_regs *regs);
static int printbinary(char *buf, unsigned long x, int nbits) static int printbinary(char *buf, unsigned long x, int nbits)
...@@ -152,7 +152,7 @@ void show_regs(struct pt_regs *regs) ...@@ -152,7 +152,7 @@ void show_regs(struct pt_regs *regs)
printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]); printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]); printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
parisc_show_stack(current, NULL, regs); parisc_show_stack(current, regs);
} }
} }
...@@ -185,44 +185,19 @@ static void do_show_stack(struct unwind_frame_info *info) ...@@ -185,44 +185,19 @@ static void do_show_stack(struct unwind_frame_info *info)
printk(KERN_CRIT "\n"); printk(KERN_CRIT "\n");
} }
static void parisc_show_stack(struct task_struct *task, unsigned long *sp, static void parisc_show_stack(struct task_struct *task,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct unwind_frame_info info; struct unwind_frame_info info;
struct task_struct *t;
t = task ? task : current; unwind_frame_init_task(&info, task, regs);
if (regs) {
unwind_frame_init(&info, t, regs);
goto show_stack;
}
if (t == current) {
unsigned long sp;
HERE:
asm volatile ("copy %%r30, %0" : "=r"(sp));
{
struct pt_regs r;
memset(&r, 0, sizeof(struct pt_regs));
r.iaoq[0] = (unsigned long)&&HERE;
r.gr[2] = (unsigned long)__builtin_return_address(0);
r.gr[30] = sp;
unwind_frame_init(&info, current, &r);
}
} else {
unwind_frame_init_from_blocked_task(&info, t);
}
show_stack:
do_show_stack(&info); do_show_stack(&info);
} }
void show_stack(struct task_struct *t, unsigned long *sp) void show_stack(struct task_struct *t, unsigned long *sp)
{ {
return parisc_show_stack(t, sp, NULL); parisc_show_stack(t, NULL);
} }
int is_valid_bugaddr(unsigned long iaoq) int is_valid_bugaddr(unsigned long iaoq)
......
...@@ -403,9 +403,31 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct ...@@ -403,9 +403,31 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct
kfree(r2); kfree(r2);
} }
void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs) #define get_parisc_stackpointer() ({ \
unsigned long sp; \
__asm__("copy %%r30, %0" : "=r"(sp)); \
(sp); \
})
void unwind_frame_init_task(struct unwind_frame_info *info,
struct task_struct *task, struct pt_regs *regs)
{ {
unwind_frame_init(info, current, regs); task = task ? task : current;
if (task == current) {
struct pt_regs r;
if (!regs) {
memset(&r, 0, sizeof(r));
r.iaoq[0] = _THIS_IP_;
r.gr[2] = _RET_IP_;
r.gr[30] = get_parisc_stackpointer();
regs = &r;
}
unwind_frame_init(info, task, &r);
} else {
unwind_frame_init_from_blocked_task(info, task);
}
} }
int unwind_once(struct unwind_frame_info *next_frame) int unwind_once(struct unwind_frame_info *next_frame)
...@@ -442,19 +464,12 @@ int unwind_to_user(struct unwind_frame_info *info) ...@@ -442,19 +464,12 @@ int unwind_to_user(struct unwind_frame_info *info)
unsigned long return_address(unsigned int level) unsigned long return_address(unsigned int level)
{ {
struct unwind_frame_info info; struct unwind_frame_info info;
struct pt_regs r;
unsigned long sp;
/* initialize unwind info */ /* initialize unwind info */
asm volatile ("copy %%r30, %0" : "=r"(sp)); unwind_frame_init_task(&info, current, NULL);
memset(&r, 0, sizeof(struct pt_regs));
r.iaoq[0] = _THIS_IP_;
r.gr[2] = _RET_IP_;
r.gr[30] = sp;
unwind_frame_init(&info, current, &r);
/* unwind stack */ /* unwind stack */
++level; level += 2;
do { do {
if (unwind_once(&info) < 0 || info.ip == 0) if (unwind_once(&info) < 0 || info.ip == 0)
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment