]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/traps_64.c
x86: turn 64 bit x86 HANDLE_STACK into print_context_stack like 32 bit has
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / traps_64.c
index 62c4d8f46ee9db3770216890e6d09b6f2512fb65..b8303ed950571c758784bf27cdd2007f84b66021 100644 (file)
@@ -212,10 +212,46 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
  * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
  */
 
-static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
+static inline int valid_stack_ptr(struct thread_info *tinfo,
+                       void *p, unsigned int size, void *end)
 {
        void *t = (void *)tinfo;
-        return p > t && p < t + THREAD_SIZE - 3;
+       if (end) {
+               if (p < end && p >= (end-THREAD_SIZE))
+                       return 1;
+               else
+                       return 0;
+       }
+       return p > t && p < t + THREAD_SIZE - size;
+}
+
+static inline unsigned long print_context_stack(struct thread_info *tinfo,
+                               unsigned long *stack, unsigned long bp,
+                               const struct stacktrace_ops *ops, void *data,
+                               unsigned long *end)
+{
+       /*
+        * Print function call entries within a stack. 'cond' is the
+        * "end of stackframe" condition, that the 'stack++'
+        * iteration will eventually trigger.
+        */
+       while (valid_stack_ptr(tinfo, stack, 3, end)) {
+               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, 1);
+               }
+       }
+       return bp;
 }
 
 void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
@@ -229,6 +265,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
 
        if (!tsk)
                tsk = current;
+       tinfo = task_thread_info(tsk);
 
        if (!stack) {
                unsigned long dummy;
@@ -237,28 +274,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
                        stack = (unsigned long *)tsk->thread.sp;
        }
 
-       /*
-        * 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, 1);   \
-               } \
-       } while (0)
 
        /*
         * Print function call entries in all stacks, starting at the
@@ -274,7 +289,9 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
                if (estack_end) {
                        if (ops->stack(data, id) < 0)
                                break;
-                       HANDLE_STACK (stack < estack_end);
+
+                       print_context_stack(tinfo, stack, 0, ops,
+                                               data, estack_end);
                        ops->stack(data, "<EOE>");
                        /*
                         * We link to the next stack via the
@@ -292,7 +309,8 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
                        if (stack >= irqstack && stack < irqstack_end) {
                                if (ops->stack(data, "IRQ") < 0)
                                        break;
-                               HANDLE_STACK (stack < irqstack_end);
+                               print_context_stack(tinfo, stack, 0, ops,
+                                                        data, irqstack_end);
                                /*
                                 * We link to the next stack (which would be
                                 * the process stack normally) the last
@@ -310,9 +328,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
        /*
         * This handles the process stack:
         */
-       tinfo = task_thread_info(tsk);
-       HANDLE_STACK (valid_stack_ptr(tinfo, stack));
-#undef HANDLE_STACK
+       print_context_stack(tinfo, stack, 0, ops, data, NULL);
        put_cpu();
 }
 EXPORT_SYMBOL(dump_trace);