Commit 1097a979 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: remove get_users in backtrace code

From: Anton Blanchard <anton@samba.org>

The might_sleep infrastructure doesnt like our get_users in the backtrace
code, we often end up with might_sleep warnings inside might_sleep warnings.

Instead just be careful about pointers before dereferencing them.

Also remove the hack where we only printed the bottom 32bits of the WCHAN
value.
parent e90f6a29
...@@ -202,13 +202,11 @@ void show_regs(struct pt_regs * regs) ...@@ -202,13 +202,11 @@ void show_regs(struct pt_regs * regs)
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
long r;
if ((i % 4) == 0) { if ((i % 4) == 0) {
printk("\n" KERN_INFO "GPR%02d: ", i); printk("\n" KERN_INFO "GPR%02d: ", i);
} }
if (__get_user(r, &(regs->gpr[i])))
return; printk("%016lX ", regs->gpr[i]);
printk("%016lX ", r);
} }
printk("\n"); printk("\n");
/* /*
...@@ -473,6 +471,20 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, ...@@ -473,6 +471,20 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
return error; return error;
} }
static int kstack_depth_to_print = 64;
static inline int validate_sp(unsigned long sp, struct task_struct *p)
{
unsigned long stack_page = (unsigned long)p->thread_info;
if (sp < stack_page + sizeof(struct thread_struct))
return 0;
if (sp >= stack_page + THREAD_SIZE)
return 0;
return 1;
}
/* /*
* These bracket the sleeping functions.. * These bracket the sleeping functions..
*/ */
...@@ -484,24 +496,23 @@ extern void scheduling_functions_end_here(void); ...@@ -484,24 +496,23 @@ extern void scheduling_functions_end_here(void);
unsigned long get_wchan(struct task_struct *p) unsigned long get_wchan(struct task_struct *p)
{ {
unsigned long ip, sp; unsigned long ip, sp;
unsigned long stack_page = (unsigned long)p->thread_info;
int count = 0; int count = 0;
if (!p || p == current || p->state == TASK_RUNNING) if (!p || p == current || p->state == TASK_RUNNING)
return 0; return 0;
sp = p->thread.ksp; sp = p->thread.ksp;
if (!validate_sp(sp, p))
return 0;
do { do {
sp = *(unsigned long *)sp; sp = *(unsigned long *)sp;
if (sp < (stack_page + sizeof(struct thread_struct)) || if (!validate_sp(sp, p))
sp >= (stack_page + THREAD_SIZE))
return 0; return 0;
if (count > 0) { if (count > 0) {
ip = *(unsigned long *)(sp + 16); ip = *(unsigned long *)(sp + 16);
/*
* XXX we mask the upper 32 bits until procps
* gets fixed.
*/
if (ip < first_sched || ip >= last_sched) if (ip < first_sched || ip >= last_sched)
return (ip & 0xFFFFFFFF); return ip;
} }
} while (count++ < 16); } while (count++ < 16);
return 0; return 0;
...@@ -510,28 +521,30 @@ unsigned long get_wchan(struct task_struct *p) ...@@ -510,28 +521,30 @@ unsigned long get_wchan(struct task_struct *p)
void show_stack(struct task_struct *p, unsigned long *_sp) void show_stack(struct task_struct *p, unsigned long *_sp)
{ {
unsigned long ip; unsigned long ip;
unsigned long stack_page = (unsigned long)p->thread_info;
int count = 0; int count = 0;
unsigned long sp = (unsigned long)_sp; unsigned long sp = (unsigned long)_sp;
if (!p) if (sp == 0) {
if (p) {
sp = p->thread.ksp;
} else {
sp = (unsigned long)_get_SP();
p = current;
}
}
if (!validate_sp(sp, p))
return; return;
if (sp == 0)
sp = p->thread.ksp;
printk("Call Trace:\n"); printk("Call Trace:\n");
do { do {
if (__get_user(sp, (unsigned long *)sp)) sp = *(unsigned long *)sp;
break; if (!validate_sp(sp, p))
if (sp < stack_page + sizeof(struct thread_struct)) return;
break; ip = *(unsigned long *)(sp + 16);
if (sp >= stack_page + THREAD_SIZE)
break;
if (__get_user(ip, (unsigned long *)(sp + 16)))
break;
printk("[%016lx] ", ip); printk("[%016lx] ", ip);
print_symbol("%s\n", ip); print_symbol("%s\n", ip);
} while (count++ < 32); } while (count++ < kstack_depth_to_print);
} }
void dump_stack(void) void dump_stack(void)
......
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