summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2011-04-09 13:18:59 +0200
committerAurelien Jarno <aurelien@aurel32.net>2011-04-27 20:04:51 +0200
commit47f7be394aa7baf7855fe78f56b8ba4c69bf75d9 (patch)
tree9633e60e984359013a156d84e3f6c3c9ac6a0cea
parent661bfc80e876d32da8befe53ba0234d87fc0bcc2 (diff)
ioapic: Do not set irr for masked edge IRQs
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>
-rw-r--r--hw/ioapic.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 569327d1e..6c26e820e 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -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);
}