diff options
43 files changed, 270 insertions, 211 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index a6f181c..6680425 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -155,6 +155,7 @@ struct bootinfo_kernel bootinfo; struct mtx sched_lock; struct mtx Giant; +struct mtx icu_lock; struct user *proc0uarea; vm_offset_t proc0kstack; @@ -955,6 +956,7 @@ alpha_init(pfn, ptb, bim, bip, biv) mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); mtx_init(&clock_lock, "clk", MTX_SPIN | MTX_RECURSE); + mtx_init(&icu_lock, "icu", MTX_SPIN); mtx_lock(&Giant); /* diff --git a/sys/alpha/include/intr.h b/sys/alpha/include/intr.h index 6ff2271..ea71e3f 100644 --- a/sys/alpha/include/intr.h +++ b/sys/alpha/include/intr.h @@ -29,6 +29,8 @@ #ifndef _MACHINE_INTR_H_ #define _MACHINE_INTR_H_ +extern struct mtx icu_lock; + int alpha_setup_intr(const char *name, int vector, driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep, volatile long *cntp, void (*disable)(int), void (*enable)(int)); diff --git a/sys/alpha/isa/isa.c b/sys/alpha/isa/isa.c index 95c7d58..694f4c1 100644 --- a/sys/alpha/isa/isa.c +++ b/sys/alpha/isa/isa.c @@ -29,7 +29,9 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/malloc.h> @@ -52,23 +54,21 @@ static struct rman isa_drq_rman; static void isa_intr_enable(int irq) { - int s = splhigh(); + if (irq < 8) outb(IO_ICU1+1, inb(IO_ICU1+1) & ~(1 << irq)); else outb(IO_ICU2+1, inb(IO_ICU2+1) & ~(1 << (irq - 8))); - splx(s); } static void isa_intr_disable(int irq) { - int s = splhigh(); + if (irq < 8) outb(IO_ICU1+1, inb(IO_ICU1+1) | (1 << irq)); else outb(IO_ICU2+1, inb(IO_ICU2+1) | (1 << (irq - 8))); - splx(s); } intrmask_t @@ -77,8 +77,10 @@ isa_irq_pending(void) u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1); irr2 = inb(IO_ICU2); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } @@ -88,8 +90,10 @@ isa_irq_mask(void) u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1+1); irr2 = inb(IO_ICU2+1); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } @@ -289,9 +293,11 @@ isa_handle_fast_intr(void *arg) ii->intr(ii->arg); + mtx_lock_spin(&icu_lock); if (irq > 7) outb(IO_ICU2, 0x20 | (irq & 7)); outb(IO_ICU1, 0x20 | (irq > 7 ? 2 : irq)); + mtx_unlock_spin(&icu_lock); } static void @@ -311,18 +317,24 @@ isa_disable_intr(int vector) { int irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); if (irq > 7) outb(IO_ICU2, 0x20 | (irq & 7)); outb(IO_ICU1, 0x20 | (irq > 7 ? 2 : irq)); isa_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void isa_enable_intr(int vector) { - int irq = (vector - 0x800) >> 4; + int irq; + + irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); isa_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } @@ -363,7 +375,9 @@ isa_setup_intr(device_t dev, device_t child, free(ii, M_DEVBUF); return error; } + mtx_lock_spin(&icu_lock); isa_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); *cookiep = ii; @@ -380,13 +394,16 @@ isa_teardown_intr(device_t dev, device_t child, { struct isa_intr *ii = cookie; + mtx_lock_spin(&icu_lock); + isa_intr_disable(irq->r_start); + mtx_unlock_spin(&icu_lock); + if (platform.isa_teardown_intr) { platform.isa_teardown_intr(dev, child, irq, cookie); return 0; } alpha_teardown_intr(ii->ih); - isa_intr_disable(irq->r_start); return 0; } diff --git a/sys/alpha/mcbus/mcpcia.c b/sys/alpha/mcbus/mcpcia.c index ae34e76..82be484 100644 --- a/sys/alpha/mcbus/mcpcia.c +++ b/sys/alpha/mcbus/mcpcia.c @@ -29,8 +29,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <machine/md_var.h> @@ -247,6 +249,7 @@ mcpcia_attach(device_t dev) static void mcpcia_enable_intr(struct mcpcia_softc *sc, int irq) { + REGVAL(MCPCIA_INT_MASK0(sc)) |= (1 << irq); alpha_mb(); } @@ -254,6 +257,7 @@ mcpcia_enable_intr(struct mcpcia_softc *sc, int irq) static void mcpcia_disable_intr(struct mcpcia_softc *sc, int irq) { + /* * We need to write to INT_REQ as well as INT_MASK0 in case we * are trying to mask an interrupt which is already @@ -262,7 +266,7 @@ mcpcia_disable_intr(struct mcpcia_softc *sc, int irq) */ REGVAL(MCPCIA_INT_MASK0(sc)) &= ~(1 << irq); REGVAL(MCPCIA_INT_REQ(sc)) = (1 << irq); - alpha_mb(); + alpha_mb(); } static void @@ -302,7 +306,9 @@ mcpcia_disable_intr_vec(int vector) if (sc == NULL) { panic("couldn't find MCPCIA softc for vector 0x%x", vector); } + mtx_lock_spin(&icu_lock); mcpcia_disable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); } static void @@ -342,7 +348,9 @@ mcpcia_enable_intr_vec(int vector) if (sc == NULL) { panic("couldn't find MCPCIA softc for vector 0x%x", vector); } + mtx_lock_spin(&icu_lock); mcpcia_enable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); } static int @@ -405,7 +413,9 @@ mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags, mcpcia_disable_intr_vec, mcpcia_enable_intr_vec); if (error) return error; + mtx_lock_spin(&icu_lock); mcpcia_enable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at IRQ 0x%x int%c (vec 0x%x)\n", irq, intpin - 1 + 'A' , h); return (0); @@ -437,7 +447,9 @@ mcpcia_teardown_intr(device_t dev, device_t child, struct resource *i, void *c) } else { return (ENXIO); } + mtx_lock_spin(&icu_lock); mcpcia_disable_intr(sc, irq); + mtx_unlock_spin(&icu_lock); alpha_teardown_intr(c); return (rman_deactivate_resource(i)); } diff --git a/sys/alpha/pci/apecs.c b/sys/alpha/pci/apecs.c index ebe350b..c74e940 100644 --- a/sys/alpha/pci/apecs.c +++ b/sys/alpha/pci/apecs.c @@ -58,8 +58,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -304,15 +306,23 @@ apecs_attach(device_t dev) static void apecs_disable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void apecs_enable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } static int @@ -342,7 +352,9 @@ apecs_setup_intr(device_t dev, device_t child, return error; /* Enable PCI interrupt */ + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at APECS irq %d\n", (int) irq->r_start); diff --git a/sys/alpha/pci/cia.c b/sys/alpha/pci/cia.c index 09436e3..40f205c 100644 --- a/sys/alpha/pci/cia.c +++ b/sys/alpha/pci/cia.c @@ -94,8 +94,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -513,15 +515,23 @@ cia_attach(device_t dev) static void cia_disable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void cia_enable_intr(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } static int @@ -544,7 +554,9 @@ cia_setup_intr(device_t dev, device_t child, return error; /* Enable PCI interrupt */ + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at CIA irq %d\n", (int) irq->r_start); diff --git a/sys/alpha/pci/t2.c b/sys/alpha/pci/t2.c index d9d0b9d..3dcfe35 100644 --- a/sys/alpha/pci/t2.c +++ b/sys/alpha/pci/t2.c @@ -55,8 +55,10 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/module.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -460,6 +462,7 @@ t2_enable_vec(int vector) hose = (vector >= 0xC00); irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); if (pci_int_type[hose]) { /* Write the air register on the T3/T4 with the @@ -481,6 +484,7 @@ t2_enable_vec(int vector) /* Old style 8259 (Gack!!!) interrupts */ t2_8259_enable_mask(irq); } + mtx_unlock_spin(&icu_lock); } static void @@ -492,6 +496,7 @@ t2_disable_vec(int vector) hose = (vector >= 0xC00); irq = (vector - 0x800) >> 4; + mtx_lock_spin(&icu_lock); if (pci_int_type[hose]) { /* Write the air register on the T3/T4 wioth the @@ -515,6 +520,7 @@ t2_disable_vec(int vector) /* Old style 8259 (Gack!!!) interrupts */ t2_8259_disable_mask(irq); } + mtx_unlock_spin(&icu_lock); } @@ -590,12 +596,14 @@ t2_teardown_intr(device_t dev, device_t child, t2_shadow_mask |= (1UL << mask); + mtx_lock_spin(&icu_lock); if (mask <= 7) outb(SLAVE0_ICU, t2_shadow_mask); else if (mask <= 15) outb(SLAVE1_ICU, t2_shadow_mask >> 8); else outb(SLAVE2_ICU, t2_shadow_mask >> 16); + mtx_unlock_spin(&icu_lock); alpha_teardown_intr(cookie); return rman_deactivate_resource(irq); @@ -607,7 +615,9 @@ static void t2_dispatch_intr(void *frame, unsigned long vector) { alpha_dispatch_intr(frame, vector); + mtx_lock_spin(&icu_lock); t2_eoi(vector); + mtx_unlock_spin(&icu_lock); } static void diff --git a/sys/alpha/pci/tsunami.c b/sys/alpha/pci/tsunami.c index 1ca0803..3ca127b 100644 --- a/sys/alpha/pci/tsunami.c +++ b/sys/alpha/pci/tsunami.c @@ -31,7 +31,9 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <sys/proc.h> @@ -305,15 +307,23 @@ tsunami_attach(device_t dev) static void tsunami_disable_intr_vec(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_disable(irq); + mtx_unlock_spin(&icu_lock); } static void tsunami_enable_intr_vec(int vector) { - int irq = (vector - 0x900) >> 4; + int irq; + + irq = (vector - 0x900) >> 4; + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq); + mtx_unlock_spin(&icu_lock); } static int @@ -335,7 +345,9 @@ tsunami_setup_intr(device_t dev, device_t child, return error; /* Enable PCI interrupt */ + mtx_lock_spin(&icu_lock); platform.pci_intr_enable(irq->r_start); + mtx_unlock_spin(&icu_lock); device_printf(child, "interrupting at TSUNAMI irq %d\n", (int) irq->r_start); @@ -391,7 +403,6 @@ tsunami_intr_disable(int irq) saved_mask = *mask; alpha_mb(); alpha_mb(); - } diff --git a/sys/alpha/tlsb/dwlpx.c b/sys/alpha/tlsb/dwlpx.c index 2f778ef..939fd69 100644 --- a/sys/alpha/tlsb/dwlpx.c +++ b/sys/alpha/tlsb/dwlpx.c @@ -63,7 +63,9 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/lock.h> #include <sys/module.h> +#include <sys/mutex.h> #include <sys/bus.h> #include <machine/bus.h> #include <machine/md_var.h> @@ -344,7 +346,7 @@ dwlpx_enadis_intr(int vector, int intpin, int onoff) { unsigned long paddr; u_int32_t val; - int device, ionode, hose, hpc, s; + int device, ionode, hose, hpc; ionode = DWLPX_MVEC_IONODE(vector); hose = DWLPX_MVEC_HOSE(vector); @@ -363,16 +365,15 @@ dwlpx_enadis_intr(int vector, int intpin, int onoff) device -= 8; } intpin <<= (device << 2); + mtx_lock_spin(&icu_lock); val = imaskcache[ionode][hose][hpc]; if (onoff) val |= intpin; else val &= ~intpin; imaskcache[ionode][hose][hpc] = val; - s = splhigh(); REGVAL(PCIA_IMASK(hpc) + paddr) = val; - alpha_mb(); - splx(s); + mtx_unlock_spin(&icu_lock); } static int diff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S index 3d7a687..6147b31 100644 --- a/sys/amd64/amd64/apic_vector.S +++ b/sys/amd64/amd64/apic_vector.S @@ -7,8 +7,6 @@ #include <machine/apic.h> #include <machine/smp.h> -#include "i386/isa/intr_machdep.h" - /* convert an absolute IRQ# into a bitmask */ #define IRQ_BIT(irq_num) (1 << (irq_num)) @@ -67,7 +65,7 @@ IDTVEC(vec_name) ; \ #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 #define MASK_IRQ(irq_num) \ - IMASK_LOCK ; /* into critical reg */ \ + ICU_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), apic_imen ; \ jne 7f ; /* masked, don't mask */ \ orl $IRQ_BIT(irq_num), apic_imen ; /* set the mask bit */ \ @@ -78,7 +76,7 @@ IDTVEC(vec_name) ; \ orl $IOART_INTMASK, %eax ; /* set the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ 7: ; /* already masked */ \ - IMASK_UNLOCK + ICU_UNLOCK /* * Test to see whether we are handling an edge or level triggered INT. * Level-triggered INTs must still be masked as we don't clear the source, @@ -113,7 +111,7 @@ IDTVEC(vec_name) ; \ * Test to see if the source is currently masked, clear if so. */ #define UNMASK_IRQ(irq_num) \ - IMASK_LOCK ; /* into critical reg */ \ + ICU_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), _apic_imen ; \ je 7f ; /* bit clear, not masked */ \ andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \ @@ -124,7 +122,7 @@ IDTVEC(vec_name) ; \ andl $~IOART_INTMASK, %eax ; /* clear the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ 7: ; /* already unmasked */ \ - IMASK_UNLOCK + ICU_UNLOCK /* * Slow, threaded interrupts. diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index 34a822a..5d44aaa 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -82,6 +82,7 @@ #include <i386/isa/isa.h> #endif #endif +#include <i386/isa/intr_machdep.h> #include <isa/isavar.h> /* @@ -425,7 +426,9 @@ no_irq13: * XXX hack around brokenness of bus_teardown_intr(). If we left the * irq active then we would get it instead of exception 16. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << irq_num); + mtx_unlock_spin(&icu_lock); bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res); diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index c2ef5dc..349a140 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -211,6 +211,7 @@ static struct pcpu __pcpu; struct mtx sched_lock; struct mtx Giant; +struct mtx icu_lock; static void cpu_startup(dummy) @@ -1744,9 +1745,7 @@ init386(first) mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); mtx_init(&clock_lock, "clk", MTX_SPIN | MTX_RECURSE); -#ifdef SMP - mtx_init(&imen_mtx, "imen", MTX_SPIN); -#endif + mtx_init(&icu_lock, "icu", MTX_SPIN); mtx_lock(&Giant); /* make ldt memory segments */ diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index e8da25b..1feb66a 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -320,9 +320,6 @@ static void release_aps(void *dummy); * initialize all the SMP locks */ -/* critical region around IO APIC, apic_imen */ -struct mtx imen_mtx; - /* lock region used by kernel profiling */ int mcount_lock; diff --git a/sys/amd64/amd64/mptable.c b/sys/amd64/amd64/mptable.c index e8da25b..1feb66a 100644 --- a/sys/amd64/amd64/mptable.c +++ b/sys/amd64/amd64/mptable.c @@ -320,9 +320,6 @@ static void release_aps(void *dummy); * initialize all the SMP locks */ -/* critical region around IO APIC, apic_imen */ -struct mtx imen_mtx; - /* lock region used by kernel profiling */ int mcount_lock; diff --git a/sys/amd64/amd64/tsc.c b/sys/amd64/amd64/tsc.c index a7aaea0..a39f773 100644 --- a/sys/amd64/amd64/tsc.c +++ b/sys/amd64/amd64/tsc.c @@ -1026,7 +1026,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, &clkdesc); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); #else /* APIC_IO */ @@ -1037,7 +1039,9 @@ cpu_initclocks() */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(IRQ0); + mtx_unlock_spin(&icu_lock); #endif /* APIC_IO */ @@ -1060,11 +1064,13 @@ cpu_initclocks() inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); #ifdef APIC_IO INTREN(APIC_IRQ8); #else INTREN(IRQ8); #endif /* APIC_IO */ + mtx_unlock_spin(&icu_lock); writertc(RTC_STATUSB, rtc_statusb); @@ -1081,7 +1087,9 @@ cpu_initclocks() * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " @@ -1104,7 +1112,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); } } diff --git a/sys/amd64/include/apicreg.h b/sys/amd64/include/apicreg.h index 6345ce7..70b8011 100644 --- a/sys/amd64/include/apicreg.h +++ b/sys/amd64/include/apicreg.h @@ -458,28 +458,4 @@ typedef struct IOAPIC ioapic_t; #define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */ -#ifdef LOCORE - -#ifdef SMP - -/* - * Protects the IO APIC and apic_imen as a critical region. - */ -#define IMASK_LOCK MTX_LOCK_SPIN(imen_mtx, 0) -#define IMASK_UNLOCK MTX_UNLOCK_SPIN(imen_mtx) - -#else /* SMP */ - -#define IMASK_LOCK /* NOP */ -#define IMASK_UNLOCK /* NOP */ - -#endif /* SMP */ - -#else /* LOCORE */ - -/* global data in mp_machdep.c */ -extern struct mtx imen_mtx; - -#endif /* LOCORE */ - #endif /* _MACHINE_APIC_H_ */ diff --git a/sys/amd64/include/mptable.h b/sys/amd64/include/mptable.h index e8da25b..1feb66a 100644 --- a/sys/amd64/include/mptable.h +++ b/sys/amd64/include/mptable.h @@ -320,9 +320,6 @@ static void release_aps(void *dummy); * initialize all the SMP locks */ -/* critical region around IO APIC, apic_imen */ -struct mtx imen_mtx; - /* lock region used by kernel profiling */ int mcount_lock; diff --git a/sys/amd64/isa/clock.c b/sys/amd64/isa/clock.c index a7aaea0..a39f773 100644 --- a/sys/amd64/isa/clock.c +++ b/sys/amd64/isa/clock.c @@ -1026,7 +1026,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, &clkdesc); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); #else /* APIC_IO */ @@ -1037,7 +1039,9 @@ cpu_initclocks() */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(IRQ0); + mtx_unlock_spin(&icu_lock); #endif /* APIC_IO */ @@ -1060,11 +1064,13 @@ cpu_initclocks() inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); #ifdef APIC_IO INTREN(APIC_IRQ8); #else INTREN(IRQ8); #endif /* APIC_IO */ + mtx_unlock_spin(&icu_lock); writertc(RTC_STATUSB, rtc_statusb); @@ -1081,7 +1087,9 @@ cpu_initclocks() * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " @@ -1104,7 +1112,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); } } diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c index c17806f..3d20f9f 100644 --- a/sys/amd64/isa/intr_machdep.c +++ b/sys/amd64/isa/intr_machdep.c @@ -289,14 +289,13 @@ isa_nmi(cd) void icu_reinit() { int i; - u_int32_t eflags; - eflags = read_eflags(); - disable_intr(); + + mtx_lock_spin(&icu_lock); init_i8259(); for(i=0;i<ICU_LEN;i++) if(intr_handler[i] != isa_strayintr) INTREN(1<<i); - write_eflags(eflags); + mtx_unlock_spin(&icu_lock); } /* @@ -312,7 +311,9 @@ isa_defaultirq() /* icu vectors */ for (i = 0; i < ICU_LEN; i++) icu_unset(i, (driver_intr_t *)NULL); + mtx_lock_spin(&icu_lock); init_i8259(); + mtx_unlock_spin(&icu_lock); } @@ -406,8 +407,10 @@ isa_irq_pending() u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1); irr2 = inb(IO_ICU2); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } #endif @@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) int vector; u_int32_t value; /* the window register is 32 bits */ #endif /* FAST_HI */ - u_long ef; #if defined(APIC_IO) if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */ @@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) return (EBUSY); #endif - ef = read_eflags(); - disable_intr(); + mtx_lock_spin(&icu_lock); intr_handler[intr] = handler; intr_unit[intr] = arg; #ifdef FAST_HI @@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -542,14 +543,12 @@ icu_unset(intr, handler) int intr; driver_intr_t *handler; { - u_long ef; if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) return (EINVAL); + mtx_lock_spin(&icu_lock); INTRDIS(1 << intr); - ef = read_eflags(); - disable_intr(); intr_countp[intr] = &intrcnt[1 + intr]; intr_handler[intr] = isa_strayintr; intr_unit[intr] = &intr_unit[intr]; @@ -564,7 +563,7 @@ icu_unset(intr, handler) setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -580,14 +579,18 @@ static void ithread_enable(int vector) { + mtx_lock_spin(&icu_lock); INTREN(1 << vector); + mtx_unlock_spin(&icu_lock); } static void ithread_disable(int vector) { + mtx_lock_spin(&icu_lock); INTRDIS(1 << vector); + mtx_unlock_spin(&icu_lock); } int diff --git a/sys/amd64/isa/intr_machdep.h b/sys/amd64/isa/intr_machdep.h index 39bffb9..1726635 100644 --- a/sys/amd64/isa/intr_machdep.h +++ b/sys/amd64/isa/intr_machdep.h @@ -126,7 +126,15 @@ #endif /* SMP || APIC_IO */ -#ifndef LOCORE +#ifdef LOCORE + +/* + * Protects the IO APIC, 8259 PIC, imen, and apic_imen + */ +#define ICU_LOCK MTX_LOCK_SPIN(icu_lock, 0) +#define ICU_UNLOCK MTX_UNLOCK_SPIN(icu_lock) + +#else /* LOCORE */ /* * Type of the first (asm) part of an interrupt handler. @@ -139,6 +147,7 @@ extern u_long *intr_countp[]; /* pointers into intrcnt[] */ extern driver_intr_t *intr_handler[]; /* C entry points of intr handlers */ extern struct ithd *ithds[]; extern void *intr_unit[]; /* cookies to pass to intr handlers */ +extern struct mtx icu_lock; inthand_t IDTVEC(fastintr0), IDTVEC(fastintr1), diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c index c17806f..3d20f9f 100644 --- a/sys/amd64/isa/nmi.c +++ b/sys/amd64/isa/nmi.c @@ -289,14 +289,13 @@ isa_nmi(cd) void icu_reinit() { int i; - u_int32_t eflags; - eflags = read_eflags(); - disable_intr(); + + mtx_lock_spin(&icu_lock); init_i8259(); for(i=0;i<ICU_LEN;i++) if(intr_handler[i] != isa_strayintr) INTREN(1<<i); - write_eflags(eflags); + mtx_unlock_spin(&icu_lock); } /* @@ -312,7 +311,9 @@ isa_defaultirq() /* icu vectors */ for (i = 0; i < ICU_LEN; i++) icu_unset(i, (driver_intr_t *)NULL); + mtx_lock_spin(&icu_lock); init_i8259(); + mtx_unlock_spin(&icu_lock); } @@ -406,8 +407,10 @@ isa_irq_pending() u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1); irr2 = inb(IO_ICU2); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } #endif @@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) int vector; u_int32_t value; /* the window register is 32 bits */ #endif /* FAST_HI */ - u_long ef; #if defined(APIC_IO) if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */ @@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) return (EBUSY); #endif - ef = read_eflags(); - disable_intr(); + mtx_lock_spin(&icu_lock); intr_handler[intr] = handler; intr_unit[intr] = arg; #ifdef FAST_HI @@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -542,14 +543,12 @@ icu_unset(intr, handler) int intr; driver_intr_t *handler; { - u_long ef; if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) return (EINVAL); + mtx_lock_spin(&icu_lock); INTRDIS(1 << intr); - ef = read_eflags(); - disable_intr(); intr_countp[intr] = &intrcnt[1 + intr]; intr_handler[intr] = isa_strayintr; intr_unit[intr] = &intr_unit[intr]; @@ -564,7 +563,7 @@ icu_unset(intr, handler) setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -580,14 +579,18 @@ static void ithread_enable(int vector) { + mtx_lock_spin(&icu_lock); INTREN(1 << vector); + mtx_unlock_spin(&icu_lock); } static void ithread_disable(int vector) { + mtx_lock_spin(&icu_lock); INTRDIS(1 << vector); + mtx_unlock_spin(&icu_lock); } int diff --git a/sys/amd64/isa/npx.c b/sys/amd64/isa/npx.c index 34a822a..5d44aaa 100644 --- a/sys/amd64/isa/npx.c +++ b/sys/amd64/isa/npx.c @@ -82,6 +82,7 @@ #include <i386/isa/isa.h> #endif #endif +#include <i386/isa/intr_machdep.h> #include <isa/isavar.h> /* @@ -425,7 +426,9 @@ no_irq13: * XXX hack around brokenness of bus_teardown_intr(). If we left the * irq active then we would get it instead of exception 16. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << irq_num); + mtx_unlock_spin(&icu_lock); bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res); diff --git a/sys/amd64/isa/vector.S b/sys/amd64/isa/vector.S index d3b7a89..0bed76f 100644 --- a/sys/amd64/isa/vector.S +++ b/sys/amd64/isa/vector.S @@ -15,6 +15,7 @@ #else #include <i386/isa/isa.h> #endif +#include <i386/isa/intr_machdep.h> #define FAST_INTR_HANDLER_USES_ES 1 #ifdef FAST_INTR_HANDLER_USES_ES diff --git a/sys/amd64/isa/vector.s b/sys/amd64/isa/vector.s index d3b7a89..0bed76f 100644 --- a/sys/amd64/isa/vector.s +++ b/sys/amd64/isa/vector.s @@ -15,6 +15,7 @@ #else #include <i386/isa/isa.h> #endif +#include <i386/isa/intr_machdep.h> #define FAST_INTR_HANDLER_USES_ES 1 #ifdef FAST_INTR_HANDLER_USES_ES diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index 3d7a687..6147b31 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -7,8 +7,6 @@ #include <machine/apic.h> #include <machine/smp.h> -#include "i386/isa/intr_machdep.h" - /* convert an absolute IRQ# into a bitmask */ #define IRQ_BIT(irq_num) (1 << (irq_num)) @@ -67,7 +65,7 @@ IDTVEC(vec_name) ; \ #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 #define MASK_IRQ(irq_num) \ - IMASK_LOCK ; /* into critical reg */ \ + ICU_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), apic_imen ; \ jne 7f ; /* masked, don't mask */ \ orl $IRQ_BIT(irq_num), apic_imen ; /* set the mask bit */ \ @@ -78,7 +76,7 @@ IDTVEC(vec_name) ; \ orl $IOART_INTMASK, %eax ; /* set the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ 7: ; /* already masked */ \ - IMASK_UNLOCK + ICU_UNLOCK /* * Test to see whether we are handling an edge or level triggered INT. * Level-triggered INTs must still be masked as we don't clear the source, @@ -113,7 +111,7 @@ IDTVEC(vec_name) ; \ * Test to see if the source is currently masked, clear if so. */ #define UNMASK_IRQ(irq_num) \ - IMASK_LOCK ; /* into critical reg */ \ + ICU_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), _apic_imen ; \ je 7f ; /* bit clear, not masked */ \ andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \ @@ -124,7 +122,7 @@ IDTVEC(vec_name) ; \ andl $~IOART_INTMASK, %eax ; /* clear the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ 7: ; /* already unmasked */ \ - IMASK_UNLOCK + ICU_UNLOCK /* * Slow, threaded interrupts. diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index c2ef5dc..349a140 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -211,6 +211,7 @@ static struct pcpu __pcpu; struct mtx sched_lock; struct mtx Giant; +struct mtx icu_lock; static void cpu_startup(dummy) @@ -1744,9 +1745,7 @@ init386(first) mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE); mtx_init(&proc0.p_mtx, "process lock", MTX_DEF); mtx_init(&clock_lock, "clk", MTX_SPIN | MTX_RECURSE); -#ifdef SMP - mtx_init(&imen_mtx, "imen", MTX_SPIN); -#endif + mtx_init(&icu_lock, "icu", MTX_SPIN); mtx_lock(&Giant); /* make ldt memory segments */ diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index e8da25b..1feb66a 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -320,9 +320,6 @@ static void release_aps(void *dummy); * initialize all the SMP locks */ -/* critical region around IO APIC, apic_imen */ -struct mtx imen_mtx; - /* lock region used by kernel profiling */ int mcount_lock; diff --git a/sys/i386/i386/mpapic.c b/sys/i386/i386/mpapic.c index 7e3478a..aa9eaefd 100644 --- a/sys/i386/i386/mpapic.c +++ b/sys/i386/i386/mpapic.c @@ -210,11 +210,11 @@ io_apic_setup_intpin(int apic, int pin) * shouldn't and stop the carnage. */ vector = NRSVIDT + pin; /* IDT vec */ - mtx_lock_spin(&imen_mtx); + mtx_lock_spin(&icu_lock); io_apic_write(apic, select, (io_apic_read(apic, select) & ~IOART_INTMASK & ~0xff)|IOART_INTMSET|vector); - mtx_unlock_spin(&imen_mtx); + mtx_unlock_spin(&icu_lock); /* we only deal with vectored INTs here */ if (apic_int_type(apic, pin) != 0) @@ -258,10 +258,10 @@ io_apic_setup_intpin(int apic, int pin) printf("IOAPIC #%d intpin %d -> irq %d\n", apic, pin, irq); vector = NRSVIDT + irq; /* IDT vec */ - mtx_lock_spin(&imen_mtx); + mtx_lock_spin(&icu_lock); io_apic_write(apic, select, flags | vector); io_apic_write(apic, select + 1, target); - mtx_unlock_spin(&imen_mtx); + mtx_unlock_spin(&icu_lock); } int diff --git a/sys/i386/i386/mptable.c b/sys/i386/i386/mptable.c index e8da25b..1feb66a 100644 --- a/sys/i386/i386/mptable.c +++ b/sys/i386/i386/mptable.c @@ -320,9 +320,6 @@ static void release_aps(void *dummy); * initialize all the SMP locks */ -/* critical region around IO APIC, apic_imen */ -struct mtx imen_mtx; - /* lock region used by kernel profiling */ int mcount_lock; diff --git a/sys/i386/i386/tsc.c b/sys/i386/i386/tsc.c index a7aaea0..a39f773 100644 --- a/sys/i386/i386/tsc.c +++ b/sys/i386/i386/tsc.c @@ -1026,7 +1026,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, &clkdesc); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); #else /* APIC_IO */ @@ -1037,7 +1039,9 @@ cpu_initclocks() */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(IRQ0); + mtx_unlock_spin(&icu_lock); #endif /* APIC_IO */ @@ -1060,11 +1064,13 @@ cpu_initclocks() inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); #ifdef APIC_IO INTREN(APIC_IRQ8); #else INTREN(IRQ8); #endif /* APIC_IO */ + mtx_unlock_spin(&icu_lock); writertc(RTC_STATUSB, rtc_statusb); @@ -1081,7 +1087,9 @@ cpu_initclocks() * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " @@ -1104,7 +1112,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); } } diff --git a/sys/i386/include/apic.h b/sys/i386/include/apic.h index 6345ce7..70b8011 100644 --- a/sys/i386/include/apic.h +++ b/sys/i386/include/apic.h @@ -458,28 +458,4 @@ typedef struct IOAPIC ioapic_t; #define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */ -#ifdef LOCORE - -#ifdef SMP - -/* - * Protects the IO APIC and apic_imen as a critical region. - */ -#define IMASK_LOCK MTX_LOCK_SPIN(imen_mtx, 0) -#define IMASK_UNLOCK MTX_UNLOCK_SPIN(imen_mtx) - -#else /* SMP */ - -#define IMASK_LOCK /* NOP */ -#define IMASK_UNLOCK /* NOP */ - -#endif /* SMP */ - -#else /* LOCORE */ - -/* global data in mp_machdep.c */ -extern struct mtx imen_mtx; - -#endif /* LOCORE */ - #endif /* _MACHINE_APIC_H_ */ diff --git a/sys/i386/include/apicreg.h b/sys/i386/include/apicreg.h index 6345ce7..70b8011 100644 --- a/sys/i386/include/apicreg.h +++ b/sys/i386/include/apicreg.h @@ -458,28 +458,4 @@ typedef struct IOAPIC ioapic_t; #define IOART_INTVEC 0x000000ff /* R/W: INTerrupt vector field */ -#ifdef LOCORE - -#ifdef SMP - -/* - * Protects the IO APIC and apic_imen as a critical region. - */ -#define IMASK_LOCK MTX_LOCK_SPIN(imen_mtx, 0) -#define IMASK_UNLOCK MTX_UNLOCK_SPIN(imen_mtx) - -#else /* SMP */ - -#define IMASK_LOCK /* NOP */ -#define IMASK_UNLOCK /* NOP */ - -#endif /* SMP */ - -#else /* LOCORE */ - -/* global data in mp_machdep.c */ -extern struct mtx imen_mtx; - -#endif /* LOCORE */ - #endif /* _MACHINE_APIC_H_ */ diff --git a/sys/i386/include/mptable.h b/sys/i386/include/mptable.h index e8da25b..1feb66a 100644 --- a/sys/i386/include/mptable.h +++ b/sys/i386/include/mptable.h @@ -320,9 +320,6 @@ static void release_aps(void *dummy); * initialize all the SMP locks */ -/* critical region around IO APIC, apic_imen */ -struct mtx imen_mtx; - /* lock region used by kernel profiling */ int mcount_lock; diff --git a/sys/i386/isa/apic_ipl.s b/sys/i386/isa/apic_ipl.s index b448193..96817ef 100644 --- a/sys/i386/isa/apic_ipl.s +++ b/sys/i386/isa/apic_ipl.s @@ -74,11 +74,7 @@ bad_mask: .asciz "bad mask" * It sets the mask bit of the associated IO APIC register. */ ENTRY(INTREN) - pushfl /* save state of EI flag */ - cli /* prevent recursion */ - IMASK_LOCK /* enter critical reg */ - - movl 8(%esp), %eax /* mask into %eax */ + movl 4(%esp), %eax /* mask into %eax */ bsfl %eax, %ecx /* get pin index */ btrl %ecx, apic_imen /* update apic_imen */ @@ -91,12 +87,10 @@ ENTRY(INTREN) jz 1f movl %ecx, (%edx) /* write the target register index */ - movl 16(%edx), %eax /* read the target register data */ + movl IOAPIC_WINDOW(%edx), %eax /* read the target register data */ andl $~IOART_INTMASK, %eax /* clear mask bit */ - movl %eax, 16(%edx) /* write the APIC register data */ + movl %eax, IOAPIC_WINDOW(%edx) /* write the APIC register data */ 1: - IMASK_UNLOCK /* exit critical reg */ - popfl /* restore old state of EI flag */ ret /* @@ -106,11 +100,7 @@ ENTRY(INTREN) * It clears the mask bit of the associated IO APIC register. */ ENTRY(INTRDIS) - pushfl /* save state of EI flag */ - cli /* prevent recursion */ - IMASK_LOCK /* enter critical reg */ - - movl 8(%esp), %eax /* mask into %eax */ + movl 4(%esp), %eax /* mask into %eax */ bsfl %eax, %ecx /* get pin index */ btsl %ecx, apic_imen /* update apic_imen */ @@ -123,10 +113,8 @@ ENTRY(INTRDIS) jz 1f movl %ecx, (%edx) /* write the target register index */ - movl 16(%edx), %eax /* read the target register data */ + movl IOAPIC_WINDOW(%edx), %eax /* read the target register data */ orl $IOART_INTMASK, %eax /* set mask bit */ - movl %eax, 16(%edx) /* write the APIC register data */ + movl %eax, IOAPIC_WINDOW(%edx) /* write the APIC register data */ 1: - IMASK_UNLOCK /* exit critical reg */ - popfl /* restore old state of EI flag */ ret diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 3d7a687..6147b31 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -7,8 +7,6 @@ #include <machine/apic.h> #include <machine/smp.h> -#include "i386/isa/intr_machdep.h" - /* convert an absolute IRQ# into a bitmask */ #define IRQ_BIT(irq_num) (1 << (irq_num)) @@ -67,7 +65,7 @@ IDTVEC(vec_name) ; \ #define REDIRIDX(irq_num) CNAME(int_to_apicintpin) + 16 * (irq_num) + 12 #define MASK_IRQ(irq_num) \ - IMASK_LOCK ; /* into critical reg */ \ + ICU_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), apic_imen ; \ jne 7f ; /* masked, don't mask */ \ orl $IRQ_BIT(irq_num), apic_imen ; /* set the mask bit */ \ @@ -78,7 +76,7 @@ IDTVEC(vec_name) ; \ orl $IOART_INTMASK, %eax ; /* set the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ 7: ; /* already masked */ \ - IMASK_UNLOCK + ICU_UNLOCK /* * Test to see whether we are handling an edge or level triggered INT. * Level-triggered INTs must still be masked as we don't clear the source, @@ -113,7 +111,7 @@ IDTVEC(vec_name) ; \ * Test to see if the source is currently masked, clear if so. */ #define UNMASK_IRQ(irq_num) \ - IMASK_LOCK ; /* into critical reg */ \ + ICU_LOCK ; /* into critical reg */ \ testl $IRQ_BIT(irq_num), _apic_imen ; \ je 7f ; /* bit clear, not masked */ \ andl $~IRQ_BIT(irq_num), _apic_imen ;/* clear mask bit */ \ @@ -124,7 +122,7 @@ IDTVEC(vec_name) ; \ andl $~IOART_INTMASK, %eax ; /* clear the mask */ \ movl %eax, IOAPIC_WINDOW(%ecx) ; /* new value */ \ 7: ; /* already unmasked */ \ - IMASK_UNLOCK + ICU_UNLOCK /* * Slow, threaded interrupts. diff --git a/sys/i386/isa/clock.c b/sys/i386/isa/clock.c index a7aaea0..a39f773 100644 --- a/sys/i386/isa/clock.c +++ b/sys/i386/isa/clock.c @@ -1026,7 +1026,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, &clkdesc); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); #else /* APIC_IO */ @@ -1037,7 +1039,9 @@ cpu_initclocks() */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(IRQ0); + mtx_unlock_spin(&icu_lock); #endif /* APIC_IO */ @@ -1060,11 +1064,13 @@ cpu_initclocks() inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); #ifdef APIC_IO INTREN(APIC_IRQ8); #else INTREN(IRQ8); #endif /* APIC_IO */ + mtx_unlock_spin(&icu_lock); writertc(RTC_STATUSB, rtc_statusb); @@ -1081,7 +1087,9 @@ cpu_initclocks() * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " @@ -1104,7 +1112,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); } } diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index c17806f..3d20f9f 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -289,14 +289,13 @@ isa_nmi(cd) void icu_reinit() { int i; - u_int32_t eflags; - eflags = read_eflags(); - disable_intr(); + + mtx_lock_spin(&icu_lock); init_i8259(); for(i=0;i<ICU_LEN;i++) if(intr_handler[i] != isa_strayintr) INTREN(1<<i); - write_eflags(eflags); + mtx_unlock_spin(&icu_lock); } /* @@ -312,7 +311,9 @@ isa_defaultirq() /* icu vectors */ for (i = 0; i < ICU_LEN; i++) icu_unset(i, (driver_intr_t *)NULL); + mtx_lock_spin(&icu_lock); init_i8259(); + mtx_unlock_spin(&icu_lock); } @@ -406,8 +407,10 @@ isa_irq_pending() u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1); irr2 = inb(IO_ICU2); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } #endif @@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) int vector; u_int32_t value; /* the window register is 32 bits */ #endif /* FAST_HI */ - u_long ef; #if defined(APIC_IO) if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */ @@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) return (EBUSY); #endif - ef = read_eflags(); - disable_intr(); + mtx_lock_spin(&icu_lock); intr_handler[intr] = handler; intr_unit[intr] = arg; #ifdef FAST_HI @@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -542,14 +543,12 @@ icu_unset(intr, handler) int intr; driver_intr_t *handler; { - u_long ef; if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) return (EINVAL); + mtx_lock_spin(&icu_lock); INTRDIS(1 << intr); - ef = read_eflags(); - disable_intr(); intr_countp[intr] = &intrcnt[1 + intr]; intr_handler[intr] = isa_strayintr; intr_unit[intr] = &intr_unit[intr]; @@ -564,7 +563,7 @@ icu_unset(intr, handler) setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -580,14 +579,18 @@ static void ithread_enable(int vector) { + mtx_lock_spin(&icu_lock); INTREN(1 << vector); + mtx_unlock_spin(&icu_lock); } static void ithread_disable(int vector) { + mtx_lock_spin(&icu_lock); INTRDIS(1 << vector); + mtx_unlock_spin(&icu_lock); } int diff --git a/sys/i386/isa/intr_machdep.h b/sys/i386/isa/intr_machdep.h index 39bffb9..1726635 100644 --- a/sys/i386/isa/intr_machdep.h +++ b/sys/i386/isa/intr_machdep.h @@ -126,7 +126,15 @@ #endif /* SMP || APIC_IO */ -#ifndef LOCORE +#ifdef LOCORE + +/* + * Protects the IO APIC, 8259 PIC, imen, and apic_imen + */ +#define ICU_LOCK MTX_LOCK_SPIN(icu_lock, 0) +#define ICU_UNLOCK MTX_UNLOCK_SPIN(icu_lock) + +#else /* LOCORE */ /* * Type of the first (asm) part of an interrupt handler. @@ -139,6 +147,7 @@ extern u_long *intr_countp[]; /* pointers into intrcnt[] */ extern driver_intr_t *intr_handler[]; /* C entry points of intr handlers */ extern struct ithd *ithds[]; extern void *intr_unit[]; /* cookies to pass to intr handlers */ +extern struct mtx icu_lock; inthand_t IDTVEC(fastintr0), IDTVEC(fastintr1), diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index c17806f..3d20f9f 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -289,14 +289,13 @@ isa_nmi(cd) void icu_reinit() { int i; - u_int32_t eflags; - eflags = read_eflags(); - disable_intr(); + + mtx_lock_spin(&icu_lock); init_i8259(); for(i=0;i<ICU_LEN;i++) if(intr_handler[i] != isa_strayintr) INTREN(1<<i); - write_eflags(eflags); + mtx_unlock_spin(&icu_lock); } /* @@ -312,7 +311,9 @@ isa_defaultirq() /* icu vectors */ for (i = 0; i < ICU_LEN; i++) icu_unset(i, (driver_intr_t *)NULL); + mtx_lock_spin(&icu_lock); init_i8259(); + mtx_unlock_spin(&icu_lock); } @@ -406,8 +407,10 @@ isa_irq_pending() u_char irr1; u_char irr2; + mtx_lock_spin(&icu_lock); irr1 = inb(IO_ICU1); irr2 = inb(IO_ICU2); + mtx_unlock_spin(&icu_lock); return ((irr2 << 8) | irr1); } #endif @@ -473,7 +476,6 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) int vector; u_int32_t value; /* the window register is 32 bits */ #endif /* FAST_HI */ - u_long ef; #if defined(APIC_IO) if ((u_int)intr >= ICU_LEN) /* no 8259 SLAVE to ignore */ @@ -486,8 +488,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) return (EBUSY); #endif - ef = read_eflags(); - disable_intr(); + mtx_lock_spin(&icu_lock); intr_handler[intr] = handler; intr_unit[intr] = arg; #ifdef FAST_HI @@ -528,7 +529,7 @@ icu_setup(int intr, driver_intr_t *handler, void *arg, int flags) SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ INTREN(1 << intr); - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -542,14 +543,12 @@ icu_unset(intr, handler) int intr; driver_intr_t *handler; { - u_long ef; if ((u_int)intr >= ICU_LEN || handler != intr_handler[intr]) return (EINVAL); + mtx_lock_spin(&icu_lock); INTRDIS(1 << intr); - ef = read_eflags(); - disable_intr(); intr_countp[intr] = &intrcnt[1 + intr]; intr_handler[intr] = isa_strayintr; intr_unit[intr] = &intr_unit[intr]; @@ -564,7 +563,7 @@ icu_unset(intr, handler) setidt(ICU_OFFSET + intr, slowintr[intr], SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); #endif /* FAST_HI */ - write_eflags(ef); + mtx_unlock_spin(&icu_lock); return (0); } @@ -580,14 +579,18 @@ static void ithread_enable(int vector) { + mtx_lock_spin(&icu_lock); INTREN(1 << vector); + mtx_unlock_spin(&icu_lock); } static void ithread_disable(int vector) { + mtx_lock_spin(&icu_lock); INTRDIS(1 << vector); + mtx_unlock_spin(&icu_lock); } int diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c index 34a822a..5d44aaa 100644 --- a/sys/i386/isa/npx.c +++ b/sys/i386/isa/npx.c @@ -82,6 +82,7 @@ #include <i386/isa/isa.h> #endif #endif +#include <i386/isa/intr_machdep.h> #include <isa/isavar.h> /* @@ -425,7 +426,9 @@ no_irq13: * XXX hack around brokenness of bus_teardown_intr(). If we left the * irq active then we would get it instead of exception 16. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << irq_num); + mtx_unlock_spin(&icu_lock); bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); bus_release_resource(dev, SYS_RES_IOPORT, ioport_rid, ioport_res); diff --git a/sys/i386/isa/vector.s b/sys/i386/isa/vector.s index d3b7a89..0bed76f 100644 --- a/sys/i386/isa/vector.s +++ b/sys/i386/isa/vector.s @@ -15,6 +15,7 @@ #else #include <i386/isa/isa.h> #endif +#include <i386/isa/intr_machdep.h> #define FAST_INTR_HANDLER_USES_ES 1 #ifdef FAST_INTR_HANDLER_USES_ES diff --git a/sys/isa/atrtc.c b/sys/isa/atrtc.c index a7aaea0..a39f773 100644 --- a/sys/isa/atrtc.c +++ b/sys/isa/atrtc.c @@ -1026,7 +1026,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, &clkdesc); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); #else /* APIC_IO */ @@ -1037,7 +1039,9 @@ cpu_initclocks() */ inthand_add("clk", 0, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(IRQ0); + mtx_unlock_spin(&icu_lock); #endif /* APIC_IO */ @@ -1060,11 +1064,13 @@ cpu_initclocks() inthand_add("rtc", 8, (driver_intr_t *)rtcintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); #ifdef APIC_IO INTREN(APIC_IRQ8); #else INTREN(IRQ8); #endif /* APIC_IO */ + mtx_unlock_spin(&icu_lock); writertc(RTC_STATUSB, rtc_statusb); @@ -1081,7 +1087,9 @@ cpu_initclocks() * on the IO APIC. * Workaround: Limited variant of mixed mode. */ + mtx_lock_spin(&icu_lock); INTRDIS(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); inthand_remove(clkdesc); printf("APIC_IO: Broken MP table detected: " "8254 is not connected to " @@ -1104,7 +1112,9 @@ cpu_initclocks() inthand_add("clk", apic_8254_intr, (driver_intr_t *)clkintr, NULL, INTR_TYPE_CLK | INTR_FAST, NULL); + mtx_lock_spin(&icu_lock); INTREN(1 << apic_8254_intr); + mtx_unlock_spin(&icu_lock); } } diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 5e4dc61..1c70d86 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -215,10 +215,8 @@ static struct witness_order_list_entry order_lists[] = { /* * leaf locks */ + { "icu", &lock_class_mtx_spin }, #ifdef SMP -#ifdef __i386__ - { "imen", &lock_class_mtx_spin }, -#endif { "smp rendezvous", &lock_class_mtx_spin }, #endif { "clk", &lock_class_mtx_spin }, |