Skip to content

Commit

Permalink
powerpc/irq: Don't switch to irq stack from softirq stack
Browse files Browse the repository at this point in the history
irq_exit() is now called on the irq stack, which can trigger a switch to
the softirq stack from the irq stack.  If an interrupt happens at that
point, we will not properly detect the re-entrancy and clobber the
original return context on the irq stack.

This fixes it.  The side effect is to prevent all nesting from softirq
stack to irq stack even in the "safe" case but it's simpler that way and
matches what x86_64 does.

Reported-by: Cédric Le Goater <clg@fr.ibm.com>
Tested-by: Cédric Le Goater <clg@fr.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Benjamin Herrenschmidt authored and Linus Torvalds committed Oct 7, 2013
1 parent fd84831 commit 8b5ede6
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions arch/powerpc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,14 +495,15 @@ void __do_irq(struct pt_regs *regs)
void do_IRQ(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
struct thread_info *curtp, *irqtp;
struct thread_info *curtp, *irqtp, *sirqtp;

/* Switch to the irq stack to handle this */
curtp = current_thread_info();
irqtp = hardirq_ctx[raw_smp_processor_id()];
sirqtp = softirq_ctx[raw_smp_processor_id()];

/* Already there ? */
if (unlikely(curtp == irqtp)) {
if (unlikely(curtp == irqtp || curtp == sirqtp)) {
__do_irq(regs);
set_irq_regs(old_regs);
return;
Expand Down

0 comments on commit 8b5ede6

Please sign in to comment.