X-Git-Url: http://git.onelab.eu/?p=linux-2.6.git;a=blobdiff_plain;f=arch%2Fsparc64%2Fkernel%2Fstacktrace.c;fp=arch%2Fsparc64%2Fkernel%2Fstacktrace.c;h=c4d15f2762b9e37579b73bc3e11e6219682b65b8;hp=0000000000000000000000000000000000000000;hb=76828883507a47dae78837ab5dec5a5b4513c667;hpb=64ba3f394c830ec48a1c31b53dcae312c56f1604 diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c new file mode 100644 index 000000000..c4d15f276 --- /dev/null +++ b/arch/sparc64/kernel/stacktrace.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +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); +}