summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Cantrill <bryan@joyent.com>2011-12-13 07:36:50 +0000
committerBryan Cantrill <bryan@joyent.com>2011-12-13 07:36:50 +0000
commit3d2e6c9fd3135807b671a346582cf5f7cdcb0027 (patch)
treeddb184bab6eddf5bcbb2f7fa39fbb976ead48cea
parentc1086e516e7350f245dab213303af08cd0e0e834 (diff)
downloadillumos-kvm-3d2e6c9fd3135807b671a346582cf5f7cdcb0027.tar.gz
OS-688 panic assertion failed kvm_ioapic.c, line: 249
-rw-r--r--kvm_ioapic.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/kvm_ioapic.c b/kvm_ioapic.c
index 10b89a9..37dbded 100644
--- a/kvm_ioapic.c
+++ b/kvm_ioapic.c
@@ -246,7 +246,23 @@ __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int vector, int trigger_mode)
if (trigger_mode != IOAPIC_LEVEL_TRIG)
continue;
- ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
+ if (ent->fields.trig_mode != IOAPIC_LEVEL_TRIG) {
+ /*
+ * If the same vector is being used for two different
+ * I/O redirection table entries with different trigger
+ * modes, our trigger mode and the trigger mode of
+ * the entry will differ for at least one entry.
+ * Most operating systems don't do this (that is, most
+ * do not reuse a vector for interrupts with different
+ * trigger modes), but FreeBSD (at least) is a notable
+ * exception: it allocates vectors on a per-local APIC
+ * basis, and will therefore reuse the same vector for
+ * entirely different interrupt sources. In this case,
+ * we need do nothing else, and simply continue.
+ */
+ continue;
+ }
+
ent->fields.remote_irr = 0;
if (!ent->fields.mask && (ioapic->irr & (1 << i)))
ioapic_service(ioapic, i);