diff options
-rw-r--r-- | usr/src/uts/i86pc/io/apix/apix_utils.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/usr/src/uts/i86pc/io/apix/apix_utils.c b/usr/src/uts/i86pc/io/apix/apix_utils.c index 3342306db6..04e49a6e48 100644 --- a/usr/src/uts/i86pc/io/apix/apix_utils.c +++ b/usr/src/uts/i86pc/io/apix/apix_utils.c @@ -26,6 +26,9 @@ * Copyright (c) 2010, Intel Corporation. * All rights reserved. */ +/* + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + */ #include <sys/processor.h> #include <sys/time.h> @@ -1829,26 +1832,39 @@ ioapix_setup_intr(int irqno, iflag_t *flagp) 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 shouldn't 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 */ |