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

Commit eda32c21 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Greg Kroah-Hartman
Browse files

genirq: Provide IRQCHIP_AFFINITY_PRE_STARTUP



commit 826da771291fc25a428e871f9e7fb465e390f852 upstream.

X86 IO/APIC and MSI interrupts (when used without interrupts remapping)
require that the affinity setup on startup is done before the interrupt is
enabled for the first time as the non-remapped operation mode cannot safely
migrate enabled interrupts from arbitrary contexts. Provide a new irq chip
flag which allows affected hardware to request this.

This has to be opt-in because there have been reports in the past that some
interrupt chips cannot handle affinity setting before startup.

Fixes: 18404756 ("genirq: Expose default irq affinity mask (take 3)")
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Tested-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20210729222542.779791738@linutronix.de


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 06b34774
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -542,6 +542,7 @@ struct irq_chip {
 * IRQCHIP_EOI_THREADED:	Chip requires eoi() on unmask in threaded mode
 * IRQCHIP_SUPPORTS_LEVEL_MSI	Chip can provide two doorbells for Level MSIs
 * IRQCHIP_SUPPORTS_NMI:	Chip can deliver NMIs, only for root irqchips
 * IRQCHIP_AFFINITY_PRE_STARTUP:      Default affinity update before startup
 */
enum {
	IRQCHIP_SET_TYPE_MASKED		= (1 <<  0),
@@ -553,6 +554,7 @@ enum {
	IRQCHIP_EOI_THREADED		= (1 <<  6),
	IRQCHIP_SUPPORTS_LEVEL_MSI	= (1 <<  7),
	IRQCHIP_SUPPORTS_NMI		= (1 <<  8),
	IRQCHIP_AFFINITY_PRE_STARTUP	= (1 << 10),
};

#include <linux/irqdesc.h>
+4 −1
Original line number Diff line number Diff line
@@ -265,7 +265,10 @@ int irq_startup(struct irq_desc *desc, bool resend, bool force)
	} else {
		switch (__irq_startup_managed(desc, aff, force)) {
		case IRQ_STARTUP_NORMAL:
			if (d->chip->flags & IRQCHIP_AFFINITY_PRE_STARTUP)
				irq_setup_affinity(desc);
			ret = __irq_startup(desc);
			if (!(d->chip->flags & IRQCHIP_AFFINITY_PRE_STARTUP))
				irq_setup_affinity(desc);
			break;
		case IRQ_STARTUP_MANAGED: