@@ -153,6 +153,45 @@ static void pic_set_irq(void *opaque, int irq, int level)
s->irr &= ~mask;
s->last_irr &= ~mask;
}
+
+ /* Back-migration compatibility hack:
+ * As of late 2012, the PIT timer model was incorrectly
+ * pulsing the the IRQ0 line high for only a short time to
+ * indicate an interrupt. It counted on a conceptual bug in
+ * the PIC irq model to latch onto and and deliver the
+ * interrupt even after it became low again. (Normally lowering
+ * an IRQ line before it is serviced should cancel the
+ * interrupt.)
+ *
+ * In late 2012 the model has been improved to match hardware
+ * much better by only pulsing low for a short time (in most
+ * PIT modes), but unfortunately that means if you back-migrate
+ * a guest to a version without this fix, the next interrupt
+ * won't have its own leading edge at all, and will
+ * be lost.
+ *
+ * The following hack will allow both the current
+ * interrupt to be serviced properly, and the next one
+ * as well, regardless of which version the migration is
+ * restored on.
+ *
+ * Unfortunately, this has a small possibility of causing
+ * an extra IRQ0 in cases that would not have in the old 2012
+ * model, nor on real hardware. Specifically, if the current
+ * interrupt is processed, and then something causes an
+ * pit_irq_timer_update() to the same high level it was previously
+ * updated with. Re-setting various PIT modes (like 4) could
+ * do this, for example.
+ *
+ * At some point in the future (years from now?),
+ * when back-migration to the old 2012 version is
+ * no longer important, it should be safe to just delete
+ * this hack.
+ */
+ if (irq==0 && s->master) {
+ s->last_irr &= ~1;
+ }
+
pic_update_irq(s);
}
Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net> --- It is not at all clear that this is the best way to handle this. See the detailed notes in the cover letter of this patch series. UPDATE: Also, some fixes moved the leading edge by 1 CLK tick (CLK ticks at about 1.1 MHz), and some strategies like this might risk extra interrupts just from that. ------ hw/i8259.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)