qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] tests/functional: Convert the kvm_xen_guest avocado test


From: David Woodhouse
Subject: Re: [PATCH] tests/functional: Convert the kvm_xen_guest avocado test
Date: Wed, 18 Dec 2024 23:11:54 +0100
User-agent: Evolution 3.52.3-0ubuntu1

On Wed, 2024-12-18 at 22:42 +0100, David Woodhouse wrote:
> 
> It seems like it's because of the way QEMU handles shared level-
> triggered interrupts.

Yeah, this hack seems to confirm it. As I said, PCI INTx manages to
demux correctly, but any time you have non-PCI interrupt sharing, it's
hosed because they all just set/clear the GSI as if they own it, and
there's no OR gate in sight.

Now I have to decide if this is going to provoke me into attempting to
fix it for the general case with callbacks and fixing VFIO resampling
too, or whether I paper over it for QEMU with something *slightly* less
icky than this (which ideally would not lose levels from PCI devices
either)...

diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
index 07bd0c9ab8..4c2e8876e5 100644
--- a/hw/i386/kvm/xen_evtchn.c
+++ b/hw/i386/kvm/xen_evtchn.c
@@ -301,7 +301,20 @@ static void gsi_assert_bh(void *opaque)
         xen_evtchn_set_callback_level(!!vi->evtchn_upcall_pending);
     }
 }
-
+int xen_evtchn_check_gsi(int n, int level)
+{
+    struct vcpu_info *vi = kvm_xen_get_vcpu_info_hva(0);
+    XenEvtchnState *s = xen_evtchn_singleton;
+    if (!s || n != s->callback_gsi || !vi) {
+        return level;
+    }
+    if (vi->evtchn_upcall_pending && !level) {
+        printf("Refusing to deassert GSI#%d which is asserted by Xen\n",
+               n);
+        return 1;
+    }
+    return level;
+}
 void xen_evtchn_create(unsigned int nr_gsis, qemu_irq *system_gsis)
 {
     XenEvtchnState *s = XEN_EVTCHN(sysbus_create_simple(TYPE_XEN_EVTCHN,
diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h
index b740acfc0d..c1f56869b3 100644
--- a/hw/i386/kvm/xen_evtchn.h
+++ b/hw/i386/kvm/xen_evtchn.h
@@ -31,6 +31,7 @@ struct kvm_irq_routing_entry;
 int xen_evtchn_translate_pirq_msi(struct kvm_irq_routing_entry *route,
                                   uint64_t address, uint32_t data);
 bool xen_evtchn_deliver_pirq_msi(uint64_t address, uint32_t data);
+int xen_evtchn_check_gsi(int n, int level);
 
 
 /*
diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index dc031af662..4185f467ee 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -452,6 +452,7 @@ void gsi_handler(void *opaque, int n, int level)
     GSIState *s = opaque;
 
     trace_x86_gsi_interrupt(n, level);
+    level = xen_evtchn_check_gsi(n, level);
     switch (n) {
     case 0 ... ISA_NUM_IRQS - 1:
         if (s->i8259_irq[n]) {

Attachment: smime.p7s
Description: S/MIME cryptographic signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]