- printk("\nCall Trace:");
- i = 0;
-
- estack_end = in_exception_stack(cpu, (unsigned long)stack);
- if (estack_end) {
- while (stack < estack_end) {
- addr = *stack++;
- if (kernel_text_address(addr)) {
- i += printk_address(addr);
- i += printk(" ");
- if (i > 50) {
- printk("\n");
- i = 0;
- }
- }
- }
- i += printk(" <EOE> ");
- i += 7;
- stack = (unsigned long *) estack_end[-2];
- }
-
- irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr);
- irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE + 64);
-
- if (stack >= irqstack && stack < irqstack_end) {
- printk("<IRQ> ");
- while (stack < irqstack_end) {
- addr = *stack++;
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+ unsigned long *stack,
+ struct stacktrace_ops *ops, void *data)
+{
+ const unsigned cpu = get_cpu();
+ unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr;
+ unsigned used = 0;
+ struct thread_info *tinfo;
+
+ if (!tsk)
+ tsk = current;
+
+ if (!stack) {
+ unsigned long dummy;
+ stack = &dummy;
+ if (tsk && tsk != current)
+ stack = (unsigned long *)tsk->thread.rsp;
+ }
+
+ /*
+ * Print function call entries within a stack. 'cond' is the
+ * "end of stackframe" condition, that the 'stack++'
+ * iteration will eventually trigger.
+ */
+#define HANDLE_STACK(cond) \
+ do while (cond) { \
+ unsigned long addr = *stack++; \
+ /* Use unlocked access here because except for NMIs \
+ we should be already protected against module unloads */ \
+ if (__kernel_text_address(addr)) { \
+ /* \
+ * If the address is either in the text segment of the \
+ * kernel, or in the region which contains vmalloc'ed \
+ * memory, it *may* be the address of a calling \
+ * routine; if so, print it so that someone tracing \
+ * down the cause of the crash will be able to figure \
+ * out the call path that was taken. \
+ */ \
+ ops->address(data, addr); \
+ } \
+ } while (0)
+
+ /*
+ * Print function call entries in all stacks, starting at the
+ * current stack address. If the stacks consist of nested
+ * exceptions
+ */
+ for (;;) {
+ char *id;
+ unsigned long *estack_end;
+ estack_end = in_exception_stack(cpu, (unsigned long)stack,
+ &used, &id);
+
+ if (estack_end) {
+ if (ops->stack(data, id) < 0)
+ break;
+ HANDLE_STACK (stack < estack_end);
+ ops->stack(data, "<EOE>");