Commit 91e564f4 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

[PATCH] Fix PA-RISC unwinding from millicode

Fix unwinding from millicode
Signed-off-by: default avatarRandolph Chung <tausq@debian.org>
Signed-off-by: default avatarRandolph Chung <tausq@parisc-linux.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e1d49330
...@@ -163,13 +163,20 @@ void show_stack(struct task_struct *task, unsigned long *s) ...@@ -163,13 +163,20 @@ void show_stack(struct task_struct *task, unsigned long *s)
struct unwind_frame_info info; struct unwind_frame_info info;
if (!task) { if (!task) {
unsigned long sp, ip, rp; unsigned long sp;
struct pt_regs *r;
HERE: HERE:
asm volatile ("copy %%r30, %0" : "=r"(sp)); asm volatile ("copy %%r30, %0" : "=r"(sp));
ip = (unsigned long)&&HERE; r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
rp = (unsigned long)__builtin_return_address(0); if (!r)
unwind_frame_init(&info, current, sp, ip, rp); return;
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);
kfree(r);
} else { } else {
unwind_frame_init_from_blocked_task(&info, task); unwind_frame_init_from_blocked_task(&info, task);
} }
...@@ -416,7 +423,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o ...@@ -416,7 +423,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
{ {
/* show_stack(NULL, (unsigned long *)regs->gr[30]); */ /* show_stack(NULL, (unsigned long *)regs->gr[30]); */
struct unwind_frame_info info; struct unwind_frame_info info;
unwind_frame_init(&info, current, regs->gr[30], regs->iaoq[0], regs->gr[2]); unwind_frame_init(&info, current, regs);
do_show_stack(&info); do_show_stack(&info);
} }
...@@ -732,7 +739,7 @@ void handle_interruption(int code, struct pt_regs *regs) ...@@ -732,7 +739,7 @@ void handle_interruption(int code, struct pt_regs *regs)
} }
if (user_mode(regs)) { if (user_mode(regs)) {
if ((fault_space>>SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) { if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
#ifdef PRINT_USER_FAULTS #ifdef PRINT_USER_FAULTS
if (fault_space == 0) if (fault_space == 0)
printk(KERN_DEBUG "User Fault on Kernel Space "); printk(KERN_DEBUG "User Fault on Kernel Space ");
......
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