xen/arm: irq: End cleanly spurious interrupt
authorJulien Grall <julien.grall@arm.com>
Mon, 28 Jan 2019 16:00:23 +0000 (16:00 +0000)
committerStefano Stabellini <sstabellini@kernel.org>
Tue, 5 Feb 2019 19:19:26 +0000 (11:19 -0800)
commit8aa276235b93eeb4f81095c638970900e19b31e5
tree25176a113e4b75d6f28e1701e5741565f8b3e06b
parent844293c73685f8198bc2f0c7c5a101b3fcfd538c
xen/arm: irq: End cleanly spurious interrupt

no_irq_type handlers are used when an IRQ does not have action attached.
This is useful to detect misconfiguration between the interrupt
controller and the software.

Currently, all the handlers will do nothing on spurious interrupt. This
means if such interrupt is received, the priority of the interrupt will
not be dropped and the processor will lose the ability to receive any
interrupt lower or equal to the priority.

Spurious interrupt can happen while releasing interrupt assigned to
guest (happen during domain destruction). The interaction is roughly

CPU0                                CPU1
release_guest_irq(A)
spin_lock(&desc->lock)
gic_remove_irq_from_guest
                                    receive IRQ A
                                    spin_lock(&desc->lock)
    desc->handler->shutdown()
      set_bit(IRQ_DISABLED)
    desc->handler = &no_irq_type
spin_unlock(&desc->lock)
                                    desc->handler->end();
                                    spin_unlock(&desc->lock)

Because the no_irq_type.end callback is implemented as a NOP, CPU1 will
not drop the priority of the interrupt. So the CPU will not be able to
receive any interrupt route to any guest afterwards.

The problem can be prevented by dropping the priority and deactivating
the interrupt via gic_hw_ops->gic_host_irq->end().

Note that, for now, interrupt used by Xen are safe because it is not
using no_irq_type on release.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/irq.c