Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc590c22 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

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: default avatarMajun <majun258@huawei.com>
Signed-off-by: default avatarThomas 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
parent eb0dc47a
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -756,7 +756,6 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
{
	struct irq_chip *chip = irq_desc_get_chip(desc);
	struct irqaction *action = desc->action;
	void *dev_id = raw_cpu_ptr(action->percpu_dev_id);
	unsigned int irq = irq_desc_get_irq(desc);
	irqreturn_t res;

@@ -765,9 +764,20 @@ void handle_percpu_devid_irq(struct irq_desc *desc)
	if (chip->irq_ack)
		chip->irq_ack(&desc->irq_data);

	if (likely(action)) {
		trace_irq_handler_entry(irq, action);
	res = action->handler(irq, dev_id);
		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)
		chip->irq_eoi(&desc->irq_data);