diff options
author | Steven Rostedt <srostedt@redhat.com> | 2014-02-06 09:41:30 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-03-06 16:56:54 -0800 |
commit | 0788aa6a23cb9d693fc5040ec774b979f1e906cd (patch) | |
tree | b1c5fd2dab9c0e11bc1747e5f6102d89d16dfcc0 /arch/x86/kernel/irq_32.c | |
parent | b807902a88c470eb06d0acdf3b6590f27f5dce81 (diff) | |
download | linux-0788aa6a23cb9d693fc5040ec774b979f1e906cd.tar.bz2 |
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/irq_32.c')
-rw-r--r-- | arch/x86/kernel/irq_32.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c index d7fcbedc9c43..f135cc2ff301 100644 --- a/arch/x86/kernel/irq_32.c +++ b/arch/x86/kernel/irq_32.c @@ -81,7 +81,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) { union irq_ctx *curctx, *irqctx; - u32 *isp, arg1, arg2; + u32 *isp, *prev_esp, arg1, arg2; curctx = (union irq_ctx *) current_thread_info(); irqctx = __this_cpu_read(hardirq_ctx); @@ -98,7 +98,10 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq) /* build the stack frame on the IRQ stack */ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); irqctx->tinfo.task = curctx->tinfo.task; - irqctx->tinfo.previous_esp = current_stack_pointer; + /* Save the next esp after thread_info */ + prev_esp = (u32 *) ((char *)irqctx + sizeof(struct thread_info) - + sizeof(long)); + *prev_esp = current_stack_pointer; if (unlikely(overflow)) call_on_stack(print_stack_overflow, isp); @@ -149,16 +152,20 @@ void do_softirq_own_stack(void) { struct thread_info *curctx; union irq_ctx *irqctx; - u32 *isp; + u32 *isp, *prev_esp; curctx = current_thread_info(); irqctx = __this_cpu_read(softirq_ctx); irqctx->tinfo.task = curctx->task; - irqctx->tinfo.previous_esp = current_stack_pointer; /* build the stack frame on the softirq stack */ isp = (u32 *) ((char *)irqctx + sizeof(*irqctx)); + /* Push the previous esp onto the stack */ + prev_esp = (u32 *) ((char *)irqctx + sizeof(struct thread_info) - + sizeof(long)); + *prev_esp = current_stack_pointer; + call_on_stack(__do_softirq, isp); } |