ioapic: Do not set irr for masked edge IRQs
authorJan Kiszka <jan.kiszka@web.de>
Sat, 9 Apr 2011 11:18:59 +0000 (13:18 +0200)
committerAurelien Jarno <aurelien@aurel32.net>
Wed, 27 Apr 2011 18:04:51 +0000 (20:04 +0200)
So far we set IRR for edge IRQs even if the pin is masked. If the guest
later on unmasks and switches the pin to level-triggered mode, irr will
remain set, causing an IRQ storm. The point is that setting IRR is not
correct in this case according to the spec, and avoiding this resolves
the issue.

Reported-and-tested-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
hw/ioapic.c

index 569327d1e96fb6f83266e9b80480da6aee7ecf9d..6c26e820e05a463d4de04c1b7688f8c2fee2aa49 100644 (file)
@@ -160,8 +160,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
                 s->irr &= ~mask;
             }
         } else {
-            /* edge triggered */
-            if (level) {
+            /* According to the 82093AA manual, we must ignore edge requests
+             * if the input pin is masked. */
+            if (level && !(entry & IOAPIC_LVT_MASKED)) {
                 s->irr |= mask;
                 ioapic_service(s);
             }