]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
i386/xen: Require split-irqchip for Xen mode
authorDavid Woodhouse <dwmw@amazon.co.uk>
Fri, 30 Dec 2022 15:54:33 +0000 (15:54 +0000)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Thu, 5 Jan 2023 19:44:33 +0000 (19:44 +0000)
We're unlikely to hook up the GSI ack notifier in the kernel for the
deprecated in-kernel irqchip. Let userspace handle it (not that qemu
does so very well even for VFIO).

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
target/i386/kvm/xen-emu.c

index cb119f43c0c1482eab935f78333a2bccd36640b9..6c0f180059916c0d4e08bfb7b2ba45c60d56c138 100644 (file)
@@ -144,6 +144,33 @@ int kvm_xen_init(KVMState *s, uint32_t hypercall_msr)
         return 0;
     }
 
+    /*
+     * Event channel delivery via GSI/PCI_INTX needs to poll the vcpu_info
+     * of vCPU0 to deassert the IRQ when ->evtchn_upcall_pending is cleared.
+     *
+     * In the kernel, there's a notifier hook on the PIC/IOAPIC which allows
+     * such things to be polled at precisely the right time. We *could* do
+     * it nicely in the kernel: check vcpu_info[0]->evtchn_upcall_pending at
+     * the moment the IRQ is acked, and see if it should be reasserted.
+     *
+     * But the in-kernel irqchip is deprecated, so we're unlikely to add
+     * that support in the kernel. Insist on using the split irqchip mode
+     * instead.
+     *
+     * This leaves us polling for the level going low in QEMU, which lacks
+     * the appropriate hooks in its PIC/IOAPIC code. Even VFIO is sending a
+     * spurious 'ack' to an INTX IRQ every time there's any MMIO access to
+     * the device (for which it has to unmap the device and trap access, for
+     * some period after an IRQ!!). In the Xen case, we do it on exit from
+     * KVM_RUN, if the flag is set to say that the GSI is currently asserted.
+     * Which is kind of icky, but less so than the VFIO one. I may fix them
+     * both later...
+     */
+    if (!kvm_kernel_irqchip_split()) {
+        error_report("kvm: Xen support requires kernel-irqchip=split");
+        return -EINVAL;
+    }
+
     s->xen_caps = xen_caps;
 
     /* Tell fw_cfg to notify the BIOS to reserve the range. */