Skip to content

Commit 8b5ede6

Browse files
ozbenhtorvalds
authored andcommitted
powerpc/irq: Don't switch to irq stack from softirq stack
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 <[email protected]> Tested-by: Cédric Le Goater <[email protected]> Signed-off-by: Benjamin Herrenschmidt <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent fd84831 commit 8b5ede6

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

arch/powerpc/kernel/irq.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,14 +495,15 @@ void __do_irq(struct pt_regs *regs)
495495
void do_IRQ(struct pt_regs *regs)
496496
{
497497
struct pt_regs *old_regs = set_irq_regs(regs);
498-
struct thread_info *curtp, *irqtp;
498+
struct thread_info *curtp, *irqtp, *sirqtp;
499499

500500
/* Switch to the irq stack to handle this */
501501
curtp = current_thread_info();
502502
irqtp = hardirq_ctx[raw_smp_processor_id()];
503+
sirqtp = softirq_ctx[raw_smp_processor_id()];
503504

504505
/* Already there ? */
505-
if (unlikely(curtp == irqtp)) {
506+
if (unlikely(curtp == irqtp || curtp == sirqtp)) {
506507
__do_irq(regs);
507508
set_irq_regs(old_regs);
508509
return;

0 commit comments

Comments
 (0)