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

m68k/psc: Fix race in installing chained IRQ handler

Fix a race where a pending interrupt could be received and the handler
called before the handler's data has been setup, by converting to
irq_set_chained_handler_and_data().

Search and conversion was done with coccinelle:

@@
expression E1, E2, E3;
@@
(
-if (irq_set_chained_handler(E1, E3) != 0)
- BUG();
|
-irq_set_chained_handler(E1, E3);
)
-irq_set_handler_data(E1, E2);
+irq_set_chained_handler_and_data(E1, E3, E2);

@@
expression E1, E2, E3;
@@
(
-if (irq_set_chained_handler(E1, E3) != 0)
- BUG();
...
|
-irq_set_chained_handler(E1, E3);
...
)
-irq_set_handler_data(E1, E2);
+irq_set_chained_handler_and_data(E1, E3, E2);

Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Julia Lawall <Julia.Lawall@lip6.fr>
Cc: Joshua Thompson <funaho@jurai.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: linux-m68k@lists.linux-m68k.org

+4 -8
+4 -8
arch/m68k/mac/psc.c
··· 148 148 149 149 void __init psc_register_interrupts(void) 150 150 { 151 - irq_set_chained_handler(IRQ_AUTO_3, psc_irq); 152 - irq_set_handler_data(IRQ_AUTO_3, (void *)0x30); 153 - irq_set_chained_handler(IRQ_AUTO_4, psc_irq); 154 - irq_set_handler_data(IRQ_AUTO_4, (void *)0x40); 155 - irq_set_chained_handler(IRQ_AUTO_5, psc_irq); 156 - irq_set_handler_data(IRQ_AUTO_5, (void *)0x50); 157 - irq_set_chained_handler(IRQ_AUTO_6, psc_irq); 158 - irq_set_handler_data(IRQ_AUTO_6, (void *)0x60); 151 + irq_set_chained_handler_and_data(IRQ_AUTO_3, psc_irq, (void *)0x30); 152 + irq_set_chained_handler_and_data(IRQ_AUTO_4, psc_irq, (void *)0x40); 153 + irq_set_chained_handler_and_data(IRQ_AUTO_5, psc_irq, (void *)0x50); 154 + irq_set_chained_handler_and_data(IRQ_AUTO_6, psc_irq, (void *)0x60); 159 155 } 160 156 161 157 void psc_irq_enable(int irq) {