[PATCH] i386: Get ebp from unwinder state when continuing fallback backtrace

Cc: jbeulich@novell.com
Signed-off-by: Andi Kleen <ak@suse.de>
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 86fa7e4..bdf949c 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -171,7 +171,7 @@
 	        unsigned long *stack,
 		struct stacktrace_ops *ops, void *data)
 {
-	unsigned long ebp;
+	unsigned long ebp = 0;
 
 	if (!task)
 		task = current;
@@ -199,6 +199,7 @@
 					stack = (void *)UNW_SP(&info);
 					if (!stack)
 						return;
+					ebp = UNW_FP(&info);
 				} else
 					ops->warning(data, "Full inexact backtrace again:\n");
 			} else if (call_trace >= 1)
@@ -207,20 +208,25 @@
 				ops->warning(data, "Full inexact backtrace again:\n");
 		} else
 			ops->warning(data, "Inexact backtrace:\n");
-	} else 	if (!stack) {
+	}
+	if (!stack) {
 		unsigned long dummy;
 		stack = &dummy;
 		if (task && task != current)
 			stack = (unsigned long *)task->thread.esp;
 	}
 
-	if (task == current) {
-		/* Grab ebp right from our regs */
-		asm ("movl %%ebp, %0" : "=r" (ebp) : );
-	} else {
-		/* ebp is the last reg pushed by switch_to */
-		ebp = *(unsigned long *) task->thread.esp;
+#ifdef CONFIG_FRAME_POINTER
+	if (!ebp) {
+		if (task == current) {
+			/* Grab ebp right from our regs */
+			asm ("movl %%ebp, %0" : "=r" (ebp) : );
+		} else {
+			/* ebp is the last reg pushed by switch_to */
+			ebp = *(unsigned long *) task->thread.esp;
+		}
 	}
+#endif
 
 	while (1) {
 		struct thread_info *context;
diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h
index 4c1a0b9..f0ac399 100644
--- a/include/asm-i386/unwind.h
+++ b/include/asm-i386/unwind.h
@@ -28,6 +28,8 @@
 #define FRAME_LINK_OFFSET    0
 #define STACK_BOTTOM(tsk)    STACK_LIMIT((tsk)->thread.esp0)
 #define STACK_TOP(tsk)       ((tsk)->thread.esp0)
+#else
+#define UNW_FP(frame) ((void)(frame), 0)
 #endif
 #define STACK_LIMIT(ptr)     (((ptr) - 1) & ~(THREAD_SIZE - 1))
 
@@ -88,6 +90,7 @@
 
 #define UNW_PC(frame) ((void)(frame), 0)
 #define UNW_SP(frame) ((void)(frame), 0)
+#define UNW_FP(frame) ((void)(frame), 0)
 
 static inline int arch_unw_user_mode(const void *info)
 {