aboutsummaryrefslogtreecommitdiffstats
path: root/unmodified_drivers
diff options
context:
space:
mode:
authorSteven Smith <ssmith@xensource.com>2006-10-31 11:38:55 +0000
committerSteven Smith <ssmith@xensource.com>2006-10-31 11:38:55 +0000
commit47132af16f616422c62befdb602903bef8f4ec5e (patch)
tree5f2f6c3703999973cf1ecfa649f4bb782777e3e8 /unmodified_drivers
parent937f23487a2784df020112d67eff7eb58987bcc3 (diff)
downloadxen-47132af16f616422c62befdb602903bef8f4ec5e.tar.gz
xen-47132af16f616422c62befdb602903bef8f4ec5e.tar.bz2
xen-47132af16f616422c62befdb602903bef8f4ec5e.zip
[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>
Diffstat (limited to 'unmodified_drivers')
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/evtchn.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
index 4bd9592754..d07250add5 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c
@@ -167,11 +167,17 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
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);