mirror of
https://github.com/torvalds/linux.git
synced 2024-09-20 23:13:00 +00:00
genirq: Robustify handle_percpu_devid_irq()
The percpu_devid handler is not robust against spurious interrupts. If a spurious interrupt happens and no action is installed then the handler crashes with a NULL pointer dereference. Add a sanity check for this and log the wreckage once in dmesg. Reported-by: Majun <majun258@huawei.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: guohanjun@huawei.com Cc: dingtianhong@huawei.com Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1609021436160.5647@nanos
This commit is contained in:
parent
eb0dc47ab6
commit
fc590c22f9
|
@ -756,7 +756,6 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
|
||||||
{
|
{
|
||||||
struct irq_chip *chip = irq_desc_get_chip(desc);
|
struct irq_chip *chip = irq_desc_get_chip(desc);
|
||||||
struct irqaction *action = desc->action;
|
struct irqaction *action = desc->action;
|
||||||
void *dev_id = raw_cpu_ptr(action->percpu_dev_id);
|
|
||||||
unsigned int irq = irq_desc_get_irq(desc);
|
unsigned int irq = irq_desc_get_irq(desc);
|
||||||
irqreturn_t res;
|
irqreturn_t res;
|
||||||
|
|
||||||
|
@ -765,9 +764,20 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
|
||||||
if (chip->irq_ack)
|
if (chip->irq_ack)
|
||||||
chip->irq_ack(&desc->irq_data);
|
chip->irq_ack(&desc->irq_data);
|
||||||
|
|
||||||
trace_irq_handler_entry(irq, action);
|
if (likely(action)) {
|
||||||
res = action->handler(irq, dev_id);
|
trace_irq_handler_entry(irq, action);
|
||||||
trace_irq_handler_exit(irq, action, res);
|
res = action->handler(irq, raw_cpu_ptr(action->percpu_dev_id));
|
||||||
|
trace_irq_handler_exit(irq, action, res);
|
||||||
|
} else {
|
||||||
|
unsigned int cpu = smp_processor_id();
|
||||||
|
bool enabled = cpumask_test_cpu(cpu, desc->percpu_enabled);
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
irq_percpu_disable(desc, cpu);
|
||||||
|
|
||||||
|
pr_err_once("Spurious%s percpu IRQ%u on CPU%u\n",
|
||||||
|
enabled ? " and unmasked" : "", irq, cpu);
|
||||||
|
}
|
||||||
|
|
||||||
if (chip->irq_eoi)
|
if (chip->irq_eoi)
|
||||||
chip->irq_eoi(&desc->irq_data);
|
chip->irq_eoi(&desc->irq_data);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user