linux/kernel/irq
Marc Zyngier fe0c52fc00 genirq: MSI: Fix freeing of unallocated MSI
While debugging an unrelated issue with the GICv3 ITS driver, the
following trace triggered:

WARNING: CPU: 1 PID: 1 at kernel/irq/irqdomain.c:1121 irq_domain_free_irqs+0x160/0x17c()
NULL pointer, cannot free irq
Modules linked in:
CPU: 1 PID: 1 Comm: swapper/0 Tainted: G        W      3.19.0-rc6+ #3690
Hardware name: FVP Base (DT)
Call trace:
[<ffffffc000089398>] dump_backtrace+0x0/0x13c
[<ffffffc0000894e4>] show_stack+0x10/0x1c
[<ffffffc00066d134>] dump_stack+0x74/0x94
[<ffffffc0000a92f8>] warn_slowpath_common+0x9c/0xd4
[<ffffffc0000a938c>] warn_slowpath_fmt+0x5c/0x80
[<ffffffc0000ee04c>] irq_domain_free_irqs+0x15c/0x17c
[<ffffffc0000ef918>] msi_domain_free_irqs+0x58/0x74
[<ffffffc000386f58>] free_msi_irqs+0xb4/0x1c0

    // The msi_prepare callback fails here

[<ffffffc0003872c0>] pci_enable_msix+0x25c/0x3d4
[<ffffffc00038746c>] pci_enable_msix_range+0x34/0x80
[<ffffffc0003924ac>] vp_try_to_find_vqs+0xec/0x528
[<ffffffc000392954>] vp_find_vqs+0x6c/0xa8
[<ffffffc0003ee2a8>] init_vq+0x120/0x248
[<ffffffc0003eefb0>] virtblk_probe+0xb0/0x6bc
[<ffffffc00038fc34>] virtio_dev_probe+0x17c/0x214
[<ffffffc0003d4a04>] driver_probe_device+0x7c/0x23c
[<ffffffc0003d4cb0>] __driver_attach+0x98/0xa0
[<ffffffc0003d2c60>] bus_for_each_dev+0x60/0xb4
[<ffffffc0003d455c>] driver_attach+0x1c/0x28
[<ffffffc0003d41b0>] bus_add_driver+0x150/0x208
[<ffffffc0003d54c0>] driver_register+0x64/0x130
[<ffffffc00038f9e8>] register_virtio_driver+0x24/0x68
[<ffffffc00091320c>] init+0x70/0xac
[<ffffffc0000828f0>] do_one_initcall+0x94/0x1d0
[<ffffffc0008e9b00>] kernel_init_freeable+0x144/0x1e4
[<ffffffc00066a434>] kernel_init+0xc/0xd8
---[ end trace f9ee562a77cc7bae ]---

The ITS msi_prepare callback having failed, we end-up trying to
free MSIs that have never been allocated. Oddly enough, the kernel
is pretty upset about it.

It turns out that this behaviour was expected before the MSI domain
was introduced (and dealt with in arch_teardown_msi_irqs).

The obvious fix is to detect this early enough and bail out.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Jiang Liu <jiang.liu@linux.intel.com>
Link: http://lkml.kernel.org/r/1422299419-6051-1-git-send-email-marc.zyngier@arm.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2015-04-08 23:28:28 +02:00
..
autoprobe.c genirq: Handle pending irqs in irq_startup() 2012-02-15 11:56:59 +01:00
chip.c genirq: Work around __irq_set_handler vs stacked domains ordering issues 2014-11-23 13:01:47 +01:00
debug.h irq: hide debug macros so they don't collide with others. 2012-04-23 12:30:03 -04:00
devres.c genirq: fix reference in devm_request_threaded_irq comment 2014-08-28 15:22:00 +02:00
dummychip.c genirq: Export dummy_irq_chip 2012-08-21 16:14:23 +02:00
generic-chip.c genirq: Generic chip: Add big endian I/O accessors 2014-11-09 04:02:00 +00:00
handle.c genirq: Export symbol no_action() 2014-03-22 11:33:09 +01:00
internals.h genirq: Prevent proc race against freeing of irq descriptors 2014-12-13 13:33:07 +01:00
irqdesc.c genirq: Prevent proc race against freeing of irq descriptors 2014-12-13 13:33:07 +01:00
irqdomain.c irqdomain: Introduce helper function irq_domain_add_hierarchy() 2014-11-23 13:01:46 +01:00
Kconfig genirq: Add generic msi irq domain support 2014-11-23 13:01:47 +01:00
Makefile genirq: Add generic msi irq domain support 2014-11-23 13:01:47 +01:00
manage.c Merge branch 'linus' into irq/core to get the GIC updates which 2015-04-08 23:26:21 +02:00
migration.c genirq: Introduce irq_do_set_affinity() to reduce duplicated code 2012-05-24 22:36:40 +02:00
msi.c genirq: MSI: Fix freeing of unallocated MSI 2015-04-08 23:28:28 +02:00
pm.c genirq / PM: Add flag for shared NO_SUSPEND interrupt lines 2015-03-04 21:42:19 +01:00
proc.c irq: use %*pb[l] to print bitmaps including cpumasks and nodemasks 2015-02-13 21:21:38 -08:00
resend.c genirq: Provide means to retrigger parent 2012-11-01 12:11:31 +01:00
settings.h genirq: Prevent spurious detection for unconditionally polled interrupts 2013-11-13 16:03:02 +01:00
spurious.c genirq: Sanitize spurious interrupt detection of threaded irqs 2014-05-03 23:15:39 +02:00