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>
This commit is contained in:
Steven Rostedt
2014-02-06 09:41:30 -05:00
committed by H. Peter Anvin
parent b807902a88
commit 0788aa6a23
4 changed files with 28 additions and 11 deletions

View File

@@ -184,14 +184,14 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs)
{
unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
unsigned long sp = (unsigned long)&regs->sp;
struct thread_info *tinfo;
u32 *prev_esp;
if (context == (sp & ~(THREAD_SIZE - 1)))
return sp;
tinfo = (struct thread_info *)context;
if (tinfo->previous_esp)
return tinfo->previous_esp;
prev_esp = (u32 *)(context + sizeof(struct thread_info) - sizeof(long));
if (prev_esp)
return (unsigned long)prev_esp;
return (unsigned long)regs;
}