diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2020-03-06 14:03:43 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2020-03-08 11:06:40 +0100 |
commit | c16816acd08697b02a53f56f8936497a9f6f6e7a (patch) | |
tree | b1862c5ad099bf0324e042dd2984f6730795472a /kernel/irq/irqdesc.c | |
parent | a740a423c36932695b01a3e920f697bc55b05fec (diff) | |
download | linux-stable-c16816acd08697b02a53f56f8936497a9f6f6e7a.tar.gz linux-stable-c16816acd08697b02a53f56f8936497a9f6f6e7a.tar.bz2 linux-stable-c16816acd08697b02a53f56f8936497a9f6f6e7a.zip |
genirq: Add protection against unsafe usage of generic_handle_irq()
In general calling generic_handle_irq() with interrupts disabled from non
interrupt context is harmless. For some interrupt controllers like the x86
trainwrecks this is outright dangerous as it might corrupt state if an
interrupt affinity change is pending.
Add infrastructure which allows to mark interrupts as unsafe and catch such
usage in generic_handle_irq().
Reported-by: sathyanarayanan.kuppuswamy@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://lkml.kernel.org/r/20200306130623.590923677@linutronix.de
Diffstat (limited to 'kernel/irq/irqdesc.c')
-rw-r--r-- | kernel/irq/irqdesc.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 98a5f10d1900..1a7723604399 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -638,9 +638,15 @@ void irq_init_desc(unsigned int irq) int generic_handle_irq(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); + struct irq_data *data; if (!desc) return -EINVAL; + + data = irq_desc_get_irq_data(desc); + if (WARN_ON_ONCE(!in_irq() && handle_enforce_irqctx(data))) + return -EPERM; + generic_handle_irq_desc(desc); return 0; } |