aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/irq
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2012-04-19 04:35:17 -0400
committerThomas Gleixner <tglx@linutronix.de>2012-04-19 07:56:56 -0400
commit1c6c69525b40eb76de8adf039409722015927dc3 (patch)
tree29ba450b43c3025c28ca9f42a81e10a0e8d9460e /kernel/irq
parentc0ecaa06d6d40cb02cd264ddb308e82f0a49ec91 (diff)
genirq: Reject bogus threaded irq requests
Requesting a threaded interrupt without a primary handler and without IRQF_ONESHOT set is dangerous. The core will use the default primary handler for it, which merily wakes the thread. For a level type interrupt this results in an interrupt storm, because the interrupt line is reenabled after the primary handler runs. The device has still the line asserted, which brings us back into the primary handler. While this works for edge type interrupts, we play it safe and reject unconditionally because we can't say for sure which type this interrupt really has. The type flags are unreliable as the underlying chip implementation can override them. And we cannot assume that developers using that interface know what they are doing. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel/irq')
-rw-r--r--kernel/irq/manage.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 89a3ea82569b..9a35ace38bb1 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1031,6 +1031,27 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
1031 * all existing action->thread_mask bits. 1031 * all existing action->thread_mask bits.
1032 */ 1032 */
1033 new->thread_mask = 1 << ffz(thread_mask); 1033 new->thread_mask = 1 << ffz(thread_mask);
1034
1035 } else if (new->handler == irq_default_primary_handler) {
1036 /*
1037 * The interrupt was requested with handler = NULL, so
1038 * we use the default primary handler for it. But it
1039 * does not have the oneshot flag set. In combination
1040 * with level interrupts this is deadly, because the
1041 * default primary handler just wakes the thread, then
1042 * the irq lines is reenabled, but the device still
1043 * has the level irq asserted. Rinse and repeat....
1044 *
1045 * While this works for edge type interrupts, we play
1046 * it safe and reject unconditionally because we can't
1047 * say for sure which type this interrupt really
1048 * has. The type flags are unreliable as the
1049 * underlying chip implementation can override them.
1050 */
1051 pr_err("genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq %d\n",
1052 irq);
1053 ret = -EINVAL;
1054 goto out_mask;
1034 } 1055 }
1035 1056
1036 if (!shared) { 1057 if (!shared) {