Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <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>

authored by

Benjamin Herrenschmidt and committed by
Linus Torvalds
8b5ede69 fd848319

+3 -2
+3 -2
arch/powerpc/kernel/irq.c
··· 495 495 void do_IRQ(struct pt_regs *regs) 496 496 { 497 497 struct pt_regs *old_regs = set_irq_regs(regs); 498 - struct thread_info *curtp, *irqtp; 498 + struct thread_info *curtp, *irqtp, *sirqtp; 499 499 500 500 /* Switch to the irq stack to handle this */ 501 501 curtp = current_thread_info(); 502 502 irqtp = hardirq_ctx[raw_smp_processor_id()]; 503 + sirqtp = softirq_ctx[raw_smp_processor_id()]; 503 504 504 505 /* Already there ? */ 505 - if (unlikely(curtp == irqtp)) { 506 + if (unlikely(curtp == irqtp || curtp == sirqtp)) { 506 507 __do_irq(regs); 507 508 set_irq_regs(old_regs); 508 509 return;