Two fixes for the interrupt subsystem:

 - Make the handling of the firmware node consistent and do not free the
   node after the domain has been created successfully. The core code
   stores a pointer to it which can lead to a use after free or double
   free.

   This used to "work" because the pointer was not stored when the initial
   code was written, but at some point later it was required to store
   it. Of course nobody noticed that the existing users break that way.

 - Handle affinity setting on inactive interrupts correctly when
   hierarchical irq domains are enabled. When interrupts are inactive with
   the modern hierarchical irqdomain design, the interrupt chips are not
   necessarily in a state where affinity changes can be handled. The legacy
   irq chip design allowed this because interrupts are immediately fully
   initialized at allocation time. X86 has a hacky workaround for this, but
   other implementations do not. This cased malfunction on GIC-V3. Instead
   of playing whack a mole to find all affected drivers, change the core
   code to store the requested affinity setting and then establish it when
   the interrupt is allocated, which makes the X86 hack go away.
genirq/affinity: Handle affinity setting on inactive interrupts correctly

Setting interrupt affinity on inactive interrupts is inconsistent when
hierarchical irq domains are enabled. The core code should just store the
affinity and not call into the irq chip driver for inactive interrupts
because the chip drivers may not be in a state to handle such requests.

X86 has a hacky workaround for that but all other irq chips have not which
causes problems e.g. on GIC V3 ITS.

Instead of adding more ugly hacks all over the place, solve the problem in
the core code. If the affinity is set on an inactive interrupt then:

    - Store it in the irq descriptors affinity mask
    - Update the effective affinity to reflect that so user space has
      a consistent view
    - Don't call into the irq chip driver

This is the core equivalent of the X86 workaround and works correctly
because the affinity setting is established in the irq chip when the
interrupt is activated later on.

Note, that this is only effective when hierarchical irq domains are enabled
by the architecture. Doing it unconditionally would break legacy irq chip
implementations.

For hierarchial irq domains this works correctly as none of the drivers can
have a dependency on affinity setting in inactive state by design.

Remove the X86 workaround as it is not longer required.

Fixes: 02edee152d6e ("x86/apic/vector: Ignore set_affinity call for inactive interrupts")
Reported-by: Ali Saidi <alisaidi@amazon.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Ali Saidi <alisaidi@amazon.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20200529015501.15771-1-alisaidi@amazon.com
Link: https://lkml.kernel.org/r/877dv2rv25.fsf@nanos.tec.linutronix.de
2 files changed