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

mfd/asic3: 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: Samuel Ortiz <sameo@linux.intel.com>
Cc: Lee Jones <lee.jones@linaro.org>

+1 -2
+1 -2
drivers/mfd/asic3.c
··· 417 417 asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), 418 418 ASIC3_INTMASK_GINTMASK); 419 419 420 - irq_set_chained_handler(asic->irq_nr, asic3_irq_demux); 420 + irq_set_chained_handler_and_data(asic->irq_nr, asic3_irq_demux, asic); 421 421 irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); 422 - irq_set_handler_data(asic->irq_nr, asic); 423 422 424 423 return 0; 425 424 }