]> www.infradead.org Git - users/dwmw2/qemu.git/commit
hw/i386/pc: Fix level interrupt sharing for Xen event channel GSI staging
authorDavid Woodhouse <dwmw@amazon.co.uk>
Thu, 19 Dec 2024 16:10:30 +0000 (16:10 +0000)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 8 Jan 2025 10:59:53 +0000 (10:59 +0000)
commit918654fc45098aad25fb5b9ffa44863ce68815c3
tree947726d39bbec1c9e30524709a945e7d516e01a5
parent22edf12a16660046f2ff42a66a023cf75effbae4
hw/i386/pc: Fix level interrupt sharing for Xen event channel GSI

The system GSIs are not designed for sharing. One device might assert a
shared interrupt with qemu_set_irq() and another might deassert it, and
the level from the first device is lost.

This could be solved by using a multiplexer which functions as an OR
gate, much like the PCI code already implements for pci_set_irq() for
muxing the INTx lines.

Alternatively, it could be solved by having a 'resample' callback which
is invoked when the interrupt is acked at the interrupt controller, and
causes the devices to re-trigger the interrupt if it should still be
pending. This is the model that VFIO in Linux uses, with a 'resampler'
eventfd that actually unmasks the interrupt on the hardware device and
thus triggers a new interrupt from it if needed. QEMU currently doesn't
use that VFIO interface correctly, and just bashes on the resampler for
every MMIO access to the device "just in case".

This does neither of those. The Xen event channel GSI support *already*
has hooks into the PC gsi_handler() code, for routing GSIs to PIRQs. So
we can implement the logical OR of the external input (from PCI INTx,
serial etc.) with the Xen event channel GSI by allowing that existing
hook to modify the 'level' being asserted.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/2731
Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
hw/i386/kvm/xen_evtchn.c
hw/i386/kvm/xen_evtchn.h
hw/i386/x86-common.c