45 lines
1.7 KiB
Diff
45 lines
1.7 KiB
Diff
# HG changeset patch
|
|
# User Steven Smith <ssmith@xensource.com>
|
|
# Date Tue Oct 31 11:38:55 2006 +0000
|
|
# Node ID 79a40acadb41fbe5e5b88b20de5fe53f4dd6b413
|
|
# parent: b2371c9e05f5146767464db8504214ae2b77c25c
|
|
[PV-ON-HVM] Don't generate lots of spurious interrupts when using event
|
|
channel upcalls.
|
|
|
|
The issue here was that the Xen platform PCI interrupt is only updated
|
|
when you return from the hypervisor into guest context, and so remained
|
|
asserted for a short interval after the interrupt handler ran. If
|
|
it happened that the first subsequent trap to the hypervisor was
|
|
for unmasking the 8259 interrupt again, the unmasking caused the interrupt
|
|
to be reinjected. This caused an edge on the chaining interrupt from
|
|
the slave PIC to the master. The platform interrupt on the slave
|
|
would then be cleared as we returned to the guest, and so you
|
|
eventually end up injecting an interrupt on the master chained
|
|
interrupt with nothing pending on the slave, which shows up as
|
|
a spurious interrupt in the guest.
|
|
|
|
Signed-off-by: Steven Smith <sos22@cam.ac.uk>
|
|
|
|
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Tue Oct 31 11:31:34 2006 +0000
|
|
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Tue Oct 31 11:38:55 2006 +0000
|
|
@@ -167,11 +167,17 @@ irqreturn_t evtchn_interrupt(int irq, vo
|
|
l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
|
|
}
|
|
}
|
|
+
|
|
+ /* Make sure the hypervisor has a chance to notice that the
|
|
+ upcall_pending condition has been cleared, so that we don't
|
|
+ try and reinject the interrupt again. */
|
|
+ (void)HYPERVISOR_xen_version(0, NULL);
|
|
+
|
|
return IRQ_HANDLED;
|
|
}
|
|
|
|
void force_evtchn_callback(void)
|
|
{
|
|
- evtchn_interrupt(0, NULL, NULL);
|
|
+ (void)HYPERVISOR_xen_version(0, NULL);
|
|
}
|
|
EXPORT_SYMBOL(force_evtchn_callback);
|
|
|