Patchwork [v6,8/8] i8259/i8254: migration workaround for timer

login
register
mail settings
Submitter Matthew Ogilvie
Date Oct. 1, 2012, 4:56 a.m.
Message ID <1349067398-9578-9-git-send-email-mmogilvi_qemu@miniinfo.net>
Download mbox | patch
Permalink /patch/188217/
State New
Headers show

Comments

Matthew Ogilvie - Oct. 1, 2012, 4:56 a.m.
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(+)

Patch

diff --git a/hw/i8259.c b/hw/i8259.c
index 1ba9b3a..4b3c6c9 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -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);
 }