[tip:irq/core] genirq: Reject bogus threaded irq requests

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit-ID:  1c6c69525b40eb76de8adf039409722015927dc3
Gitweb:     http://git.kernel.org/tip/1c6c69525b40eb76de8adf039409722015927dc3
Author:     Thomas Gleixner <tglx@xxxxxxxxxxxxx>
AuthorDate: Thu, 19 Apr 2012 10:35:17 +0200
Committer:  Thomas Gleixner <tglx@xxxxxxxxxxxxx>
CommitDate: Thu, 19 Apr 2012 13:56:56 +0200

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@xxxxxxxxxxxxx>
---
 kernel/irq/manage.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 89a3ea8..9a35ace 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)
 		 * all existing action->thread_mask bits.
 		 */
 		new->thread_mask = 1 << ffz(thread_mask);
+
+	} else if (new->handler == irq_default_primary_handler) {
+		/*
+		 * The interrupt was requested with handler = NULL, so
+		 * we use the default primary handler for it. But it
+		 * does not have the oneshot flag set. In combination
+		 * with level interrupts this is deadly, because the
+		 * default primary handler just wakes the thread, then
+		 * the irq lines is reenabled, but the device still
+		 * has the level irq asserted. Rinse and repeat....
+		 *
+		 * 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.
+		 */
+		pr_err("genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq %d\n",
+		       irq);
+		ret = -EINVAL;
+		goto out_mask;
 	}
 
 	if (!shared) {
--
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Stable Commits]     [Linux Stable Kernel]     [Linux Kernel]     [Linux USB Devel]     [Linux Video &Media]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux