diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-10 10:00:00 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-10 10:00:00 -0800 |
commit | edb16bec41db68b22799a5fbad82c3891e637565 (patch) | |
tree | d019d2fa8fbf374d810f66e1a210648e53b0c593 /arch/sparc64/kernel/stacktrace.c | |
parent | bb7320d1d96dc2e479180ae8e7a112caf0726ace (diff) | |
parent | f0882589666440d573f657cb3a1d5f66f3caa157 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6:
[SPARC64]: Fix several kprobes bugs.
[SPARC64]: Update defconfig.
[SPARC64]: dma remove extra brackets
[SPARC{32,64}]: Propagate ptrace_traceme() return value.
[SPARC64]: Replace kmalloc+memset with kzalloc
[SPARC]: Check kzalloc() return value in SUN4D irq/iommu init.
[SPARC]: Replace kmalloc+memset with kzalloc
[SPARC64]: Run ctrl-alt-del action for sun4v powerdown request.
[SPARC64]: Unaligned accesses to userspace are hard errors.
[SPARC64]: Call do_mathemu on illegal instruction traps too.
[SPARC64]: Update defconfig.
[SPARC64]: Add irqtrace/stacktrace/lockdep support.
Diffstat (limited to 'arch/sparc64/kernel/stacktrace.c')
-rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c new file mode 100644 index 00000000000..c4d15f2762b --- /dev/null +++ b/arch/sparc64/kernel/stacktrace.c @@ -0,0 +1,41 @@ +#include <linux/sched.h> +#include <linux/stacktrace.h> +#include <linux/thread_info.h> +#include <asm/ptrace.h> + +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +{ + unsigned long ksp, fp, thread_base; + struct thread_info *tp; + + if (!task) + task = current; + tp = task_thread_info(task); + if (task == current) { + flushw_all(); + __asm__ __volatile__( + "mov %%fp, %0" + : "=r" (ksp) + ); + } else + ksp = tp->ksp; + + fp = ksp + STACK_BIAS; + thread_base = (unsigned long) tp; + do { + struct reg_window *rw; + + /* Bogus frame pointer? */ + if (fp < (thread_base + sizeof(struct thread_info)) || + fp >= (thread_base + THREAD_SIZE)) + break; + + rw = (struct reg_window *) fp; + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = rw->ins[7]; + + fp = rw->ins[6] + STACK_BIAS; + } while (trace->nr_entries < trace->max_entries); +} |