Print this page
3426 assertion failed: irq < 16 on VMware hardware version 9 (apix related)
Reviewed by: Albert Lee <trisk@nexenta.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>

@@ -24,10 +24,13 @@
  */
 /*
  * Copyright (c) 2010, Intel Corporation.
  * All rights reserved.
  */
+/*
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
 
 #include <sys/processor.h>
 #include <sys/time.h>
 #include <sys/psm.h>
 #include <sys/smp_impldefs.h>

@@ -1827,30 +1830,43 @@
         apic_irq_t *irqp;
         uchar_t ioapicindex, ipin;
         ulong_t iflag;
         struct autovec *avp;
 
-        irqp = apic_irq_table[irqno];
         ioapicindex = acpi_find_ioapic(irqno);
         ASSERT(ioapicindex != 0xFF);
         ipin = irqno - apic_io_vectbase[ioapicindex];
 
-        if ((irqp != NULL) && (irqp->airq_mps_intr_index == ACPI_INDEX)) {
+        mutex_enter(&airq_mutex);
+        irqp = apic_irq_table[irqno];
+
+        /*
+         * The irq table entry should not exist unless the interrupts are shared.
+         * In that case, make sure it matches what we would initialize it to.
+         */
+        if (irqp != NULL) {
+                ASSERT(irqp->airq_mps_intr_index == ACPI_INDEX);
                 ASSERT(irqp->airq_intin_no == ipin &&
                     irqp->airq_ioapicindex == ioapicindex);
                 vecp = xv_vector(irqp->airq_cpu, irqp->airq_vector);
                 ASSERT(!IS_VECT_FREE(vecp));
+                mutex_exit(&airq_mutex);
         } else {
-                vecp = apix_alloc_intx(NULL, 0, irqno);
+                irqp = kmem_zalloc(sizeof (apic_irq_t), KM_SLEEP);
 
-                irqp = apic_irq_table[irqno];
+                irqp->airq_cpu = IRQ_UNINIT;
+                irqp->airq_origirq = (uchar_t)irqno;
                 irqp->airq_mps_intr_index = ACPI_INDEX;
                 irqp->airq_ioapicindex = ioapicindex;
                 irqp->airq_intin_no = ipin;
                 irqp->airq_iflag = *flagp;
                 irqp->airq_share++;
-                apic_record_rdt_entry(irqp, irqno);
+
+                apic_irq_table[irqno] = irqp;
+                mutex_exit(&airq_mutex);
+
+                vecp = apix_alloc_intx(NULL, 0, irqno);
         }
 
         /* copy over autovect */
         for (avp = autovect[irqno].avh_link; avp; avp = avp->av_link)
                 apix_insert_av(vecp, avp->av_intr_id, avp->av_vector,