linux/kernel/irq
Thomas Gleixner bc976233a8 genirq/msi, x86/vector: Prevent reservation mode for non maskable MSI
The new reservation mode for interrupts assigns a dummy vector when the
interrupt is allocated and assigns a real vector when the interrupt is
requested. The reservation mode prevents vector pressure when devices with
a large amount of queues/interrupts are initialized, but only a minimal
subset of those queues/interrupts is actually used.

This mode has an issue with MSI interrupts which cannot be masked. If the
driver is not careful or the hardware emits an interrupt before the device
irq is requestd by the driver then the interrupt ends up on the dummy
vector as a spurious interrupt which can cause malfunction of the device or
in the worst case a lockup of the machine.

Change the logic for the reservation mode so that the early activation of
MSI interrupts checks whether:

 - the device is a PCI/MSI device
 - the reservation mode of the underlying irqdomain is activated
 - PCI/MSI masking is globally enabled
 - the PCI/MSI device uses either MSI-X, which supports masking, or
   MSI with the maskbit supported.

If one of those conditions is false, then clear the reservation mode flag
in the irq data of the interrupt and invoke irq_domain_activate_irq() with
the reserve argument cleared. In the x86 vector code, clear the can_reserve
flag in the vector allocation data so a subsequent free_irq() won't create
the same situation again. The interrupt stays assigned to a real vector
until pci_disable_msi() is invoked and all allocations are undone.

Fixes: 4900be8360 ("x86/vector/msi: Switch to global reservation mode")
Reported-by: Alexandru Chirvasitu <achirvasub@gmail.com>
Reported-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Alexandru Chirvasitu <achirvasub@gmail.com>
Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Dou Liyang <douly.fnst@cn.fujitsu.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: Mikael Pettersson <mikpelinux@gmail.com>
Cc: Josh Poulson <jopoulso@microsoft.com>
Cc: Mihai Costache <v-micos@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-pci@vger.kernel.org
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Dexuan Cui <decui@microsoft.com>
Cc: Simon Xiao <sixiao@microsoft.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Cc: Jork Loeser <Jork.Loeser@microsoft.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: devel@linuxdriverproject.org
Cc: KY Srinivasan <kys@microsoft.com>
Cc: Alan Cox <alan@linux.intel.com>
Cc: Sakari Ailus <sakari.ailus@intel.com>,
Cc: linux-media@vger.kernel.org
Link: https://lkml.kernel.org/r/alpine.DEB.2.20.1712291406420.1899@nanos
Link: https://lkml.kernel.org/r/alpine.DEB.2.20.1712291409460.1899@nanos
2017-12-29 21:13:05 +01:00
..
Kconfig genirq: Add config option for reservation mode 2017-10-18 15:38:30 +02:00
Makefile Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:33:11 -08:00
affinity.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
autoprobe.c Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:33:11 -08:00
chip.c Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:33:11 -08:00
cpuhotplug.c genirq/cpuhotplug: Add sanity check for effective affinity mask 2017-10-09 13:26:48 +02:00
debug.h genirq: Guard handle_bad_irq log messages 2017-12-28 12:28:29 +01:00
debugfs.c genirq: Introduce IRQD_CAN_RESERVE flag 2017-12-29 21:13:04 +01:00
devres.c irq/generic-chip: Provide devm_irq_setup_generic_chip() 2017-06-21 15:53:11 +02:00
dummychip.c Merge branch 'linus' into irq/core 2015-06-05 22:25:01 +02:00
generic-chip.c kernel/irq: Extend lockdep class for request mutex 2017-12-28 12:26:35 +01:00
handle.c There has been a fair amount of activity in the docs tree this time 2017-07-03 21:13:25 -07:00
internals.h genirq/irqdomain: Rename early argument of irq_domain_activate_irq() 2017-12-29 21:13:04 +01:00
ipi.c genirq/ipi: Fixup checks against nr_cpu_ids 2017-08-20 10:49:05 +02:00
irq_sim.c genirq/irq_sim: Add a devres variant of irq_sim_init() 2017-08-16 16:40:02 +02:00
irqdesc.c arm64 updates for 4.15 2017-11-15 10:56:56 -08:00
irqdomain.c genirq/irqdomain: Rename early argument of irq_domain_activate_irq() 2017-12-29 21:13:04 +01:00
manage.c irqchip updates for 4.15, take #4 2017-11-14 11:23:05 +01:00
matrix.c genirq/matrix: Fix the precedence fix for real 2017-12-04 20:50:35 +01:00
migration.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
msi.c genirq/msi, x86/vector: Prevent reservation mode for non maskable MSI 2017-12-29 21:13:05 +01:00
pm.c genirq/PM: Properly pretend disabled state when force resuming interrupts 2017-07-17 22:32:20 +02:00
proc.c Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-11-13 17:33:11 -08:00
resend.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
settings.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
spurious.c treewide: Switch DEFINE_TIMER callbacks to struct timer_list * 2017-11-21 15:57:05 -08:00
timings.c irq/timings: Use lockdep to assert IRQs are disabled/enabled 2017-11-08 11:13:52 +01:00