summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/dumpstack_32.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2014-02-06 09:41:30 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2014-03-06 16:56:54 -0800
commit0788aa6a23cb9d693fc5040ec774b979f1e906cd (patch)
treeb1c5fd2dab9c0e11bc1747e5f6102d89d16dfcc0 /arch/x86/kernel/dumpstack_32.c
parentb807902a88c470eb06d0acdf3b6590f27f5dce81 (diff)
x86: Prepare removal of previous_esp from i386 thread_info structure
The i386 thread_info contains a previous_esp field that is used to daisy chain the different stacks for dump_stack() (ie. irq, softirq, thread stacks). The goal is to eventual make i386 handling of thread_info the same as x86_64, which means that the thread_info will not be in the stack but as a per_cpu variable. We will no longer depend on thread_info being able to daisy chain different stacks as it will only exist in one location (the thread stack). By moving previous_esp to the end of thread_info and referencing it as an offset instead of using a thread_info field, this becomes a stepping stone to moving the thread_info. The offset to get to the previous stack is rather ugly in this patch, but this is only temporary and the prev_esp will be changed in the next commit. This commit is more for sanity checks of the change. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Brian Gerst <brgerst@gmail.com> Cc: Robert Richter <rric@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/20110806012353.891757693@goodmis.org Link: http://lkml.kernel.org/r/20140206144321.608754481@goodmis.org Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/dumpstack_32.c')
-rw-r--r--arch/x86/kernel/dumpstack_32.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index f2a1770ca176..187d6a749c19 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -22,6 +22,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
const struct stacktrace_ops *ops, void *data)
{
int graph = 0;
+ u32 *prev_esp;
if (!task)
task = current;
@@ -44,9 +45,17 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
((unsigned long)stack & (~(THREAD_SIZE - 1)));
bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
- stack = (unsigned long *)context->previous_esp;
+ /* Stop if not on irq stack */
+ if (task_stack_page(task) == context)
+ break;
+
+ /* The previous esp is just above the context */
+ prev_esp = (u32 *) ((char *)context + sizeof(struct thread_info) -
+ sizeof(long));
+ stack = (unsigned long *)*prev_esp;
if (!stack)
break;
+
if (ops->stack(data, "IRQ") < 0)
break;
touch_nmi_watchdog();