diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sgi/include/intr.h | 5 | ||||
-rw-r--r-- | sys/arch/sgi/localbus/int.c | 5 | ||||
-rw-r--r-- | sys/arch/sgi/localbus/macebus.c | 5 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/intr_template.c | 19 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip27_machdep.c | 13 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/xbridge.c | 30 | ||||
-rw-r--r-- | sys/arch/sgi/xbow/xheart.c | 13 |
7 files changed, 65 insertions, 25 deletions
diff --git a/sys/arch/sgi/include/intr.h b/sys/arch/sgi/include/intr.h index 3834bfa0d28..cd20096826a 100644 --- a/sys/arch/sgi/include/intr.h +++ b/sys/arch/sgi/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.47 2016/03/06 19:42:27 mpi Exp $ */ +/* $OpenBSD: intr.h,v 1.48 2017/02/11 03:44:22 visa Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -62,7 +62,7 @@ #define IPL_MPFLOOR IPL_TTY /* Interrupt priority 'flags'. */ -#define IPL_MPSAFE 0 /* no "mpsafe" interrupts */ +#define IPL_MPSAFE 0x100 /* Interrupt sharing types. */ #define IST_NONE 0 /* none */ @@ -166,6 +166,7 @@ struct intrhand { struct evcount ih_count; int ih_flags; #define IH_ALLOCATED 0x01 +#define IH_MPSAFE 0x02 }; void intr_barrier(void *); diff --git a/sys/arch/sgi/localbus/int.c b/sys/arch/sgi/localbus/int.c index 1c970cec829..ef251db20b0 100644 --- a/sys/arch/sgi/localbus/int.c +++ b/sys/arch/sgi/localbus/int.c @@ -1,4 +1,4 @@ -/* $OpenBSD: int.c,v 1.13 2016/03/14 23:08:05 krw Exp $ */ +/* $OpenBSD: int.c,v 1.14 2017/02/11 03:44:22 visa Exp $ */ /* $NetBSD: int.c,v 1.24 2011/07/01 18:53:46 dyoung Exp $ */ /* @@ -184,6 +184,8 @@ int2_intr_establish(int irq, int level, int (*ih_fun) (void *), struct int2_intrhand **p, *q, *ih; int s; + level &= ~IPL_MPSAFE; + #ifdef DIAGNOSTIC if (irq < 0 || irq >= INT2_NINTS) panic("int2_intr_establish: illegal irq %d", irq); @@ -201,6 +203,7 @@ int2_intr_establish(int irq, int level, int (*ih_fun) (void *), ih->ih.ih_arg = ih_arg; ih->ih.ih_level = level; ih->ih.ih_irq = irq; + ih->ih.ih_flags = 0; if (ih_what != NULL) evcount_attach(&ih->ih.ih_count, ih_what, &ih->ih.ih_irq); ih->flags = 0; diff --git a/sys/arch/sgi/localbus/macebus.c b/sys/arch/sgi/localbus/macebus.c index e6aa16c0754..9fb2f72dcae 100644 --- a/sys/arch/sgi/localbus/macebus.c +++ b/sys/arch/sgi/localbus/macebus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: macebus.c,v 1.64 2016/03/06 19:42:27 mpi Exp $ */ +/* $OpenBSD: macebus.c,v 1.65 2017/02/11 03:44:22 visa Exp $ */ /* * Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se) @@ -493,6 +493,8 @@ macebus_intr_establish(int irq, uint32_t mace_irqmask, int type, int level, struct crime_intrhand **p, *q, *ih; int s; + level &= ~IPL_MPSAFE; + #ifdef DIAGNOSTIC if (irq >= CRIME_NINTS || irq < 0) panic("intr_establish: illegal irq %d", irq); @@ -507,6 +509,7 @@ macebus_intr_establish(int irq, uint32_t mace_irqmask, int type, int level, ih->ih.ih_arg = ih_arg; ih->ih.ih_level = level; ih->ih.ih_irq = irq; + ih->ih.ih_flags = 0; ih->mace_irqmask = mace_irqmask; evcount_attach(&ih->ih.ih_count, ih_what, &ih->ih.ih_irq); diff --git a/sys/arch/sgi/sgi/intr_template.c b/sys/arch/sgi/sgi/intr_template.c index ed0fdfc6517..177199babf8 100644 --- a/sys/arch/sgi/sgi/intr_template.c +++ b/sys/arch/sgi/sgi/intr_template.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr_template.c,v 1.17 2016/03/06 19:42:27 mpi Exp $ */ +/* $OpenBSD: intr_template.c,v 1.18 2017/02/11 03:44:22 visa Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -158,6 +158,7 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trapframe *frame) ih = ih->ih_next) { #ifdef MULTIPROCESSOR register_t sr; + int need_lock; #endif #if defined(INTR_HANDLER_SKIP) if (INTR_HANDLER_SKIP(ih) != 0) @@ -168,9 +169,14 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trapframe *frame) if (ih->ih_level < IPL_IPI) { sr = getsr(); ENABLEIPI(); - if (ih->ih_level < IPL_CLOCK) - __mp_lock(&kernel_lock); } + if (ih->ih_flags & IH_MPSAFE) + need_lock = 0; + else + need_lock = + ih->ih_level < IPL_CLOCK; + if (need_lock) + __mp_lock(&kernel_lock); #endif ret = (*ih->ih_fun)(ih->ih_arg); if (ret != 0) { @@ -179,11 +185,10 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trapframe *frame) &ih->ih_count.ec_count); } #ifdef MULTIPROCESSOR - if (ih->ih_level < IPL_IPI) { - if (ih->ih_level < IPL_CLOCK) - __mp_unlock(&kernel_lock); + if (need_lock) + __mp_unlock(&kernel_lock); + if (ih->ih_level < IPL_IPI) setsr(sr); - } #endif __asm__ (".set noreorder\n"); ci->ci_ipl = ipl; diff --git a/sys/arch/sgi/sgi/ip27_machdep.c b/sys/arch/sgi/sgi/ip27_machdep.c index 646e2696708..6aa9acc6749 100644 --- a/sys/arch/sgi/sgi/ip27_machdep.c +++ b/sys/arch/sgi/sgi/ip27_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip27_machdep.c,v 1.76 2016/10/27 13:19:27 visa Exp $ */ +/* $OpenBSD: ip27_machdep.c,v 1.77 2017/02/11 03:44:22 visa Exp $ */ /* * Copyright (c) 2008, 2009 Miodrag Vallat. @@ -776,6 +776,7 @@ ip27_hub_intr_establish(int (*func)(void *), void *arg, int intrbit, { struct intrhand *ih, **anchor; u_long cpuid = cpu_number(); + int flags; int s; #ifdef DIAGNOSTIC @@ -783,6 +784,9 @@ ip27_hub_intr_establish(int (*func)(void *), void *arg, int intrbit, return EINVAL; #endif + flags = (level & IPL_MPSAFE) ? IH_MPSAFE : 0; + level &= ~IPL_MPSAFE; + /* * Widget interrupts are not supposed to be shared - the interrupt * mask is supposedly large enough for all interrupt sources. @@ -802,17 +806,16 @@ ip27_hub_intr_establish(int (*func)(void *), void *arg, int intrbit, ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT); if (ih == NULL) return ENOMEM; - ih->ih_flags = IH_ALLOCATED; - } else { + flags |= IH_ALLOCATED; + } else ih = ihstore; - ih->ih_flags = 0; - } ih->ih_next = NULL; ih->ih_fun = func; ih->ih_arg = arg; ih->ih_level = level; ih->ih_irq = intrbit; + ih->ih_flags = flags; if (name != NULL) evcount_attach(&ih->ih_count, name, &ih->ih_level); diff --git a/sys/arch/sgi/xbow/xbridge.c b/sys/arch/sgi/xbow/xbridge.c index 38059d197b3..e23e30459e6 100644 --- a/sys/arch/sgi/xbow/xbridge.c +++ b/sys/arch/sgi/xbow/xbridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xbridge.c,v 1.100 2015/12/03 15:38:06 visa Exp $ */ +/* $OpenBSD: xbridge.c,v 1.101 2017/02/11 03:44:22 visa Exp $ */ /* * Copyright (c) 2008, 2009, 2011 Miodrag Vallat. @@ -1198,6 +1198,8 @@ struct xbridge_intrhandler { int (*xih_func)(void *); void *xih_arg; struct evcount xih_count; + int xih_flags; +#define XIH_MPSAFE 0x01 int xih_level; int xih_device; /* device slot number */ }; @@ -1309,11 +1311,15 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level, struct xbridge_intr *xi; struct xbridge_intrhandler *xih; uint64_t int_addr; - int intrbit = XBRIDGE_INTR_BIT(ih); int device = XBRIDGE_INTR_DEVICE(ih); + int intrbit = XBRIDGE_INTR_BIT(ih); + int flags; int intrsrc; int new; + flags = (level & IPL_MPSAFE) ? XIH_MPSAFE : 0; + level &= ~IPL_MPSAFE; + /* * Allocate bookkeeping structure if this is the * first time we're using this interrupt source. @@ -1353,7 +1359,7 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level, * XXX between devices of different levels. */ if (xbow_intr_establish(xb->xb_pci_intr_handler, xi, intrsrc, - IPL_BIO, NULL, NULL)) { + IPL_BIO | IPL_MPSAFE, NULL, NULL)) { printf("%s: unable to register interrupt handler\n", DEVNAME(xb)); return NULL; @@ -1368,6 +1374,7 @@ xbridge_intr_establish(void *cookie, pci_intr_handle_t ih, int level, xih->xih_main = xi; xih->xih_func = func; xih->xih_arg = arg; + xih->xih_flags = flags; xih->xih_level = level; xih->xih_device = device; evcount_attach(&xih->xih_count, name, &xi->xi_intrsrc); @@ -1466,8 +1473,11 @@ xbridge_pci_intr_handler(void *v) struct xbridge_intr *xi = (struct xbridge_intr *)v; struct xbpci_softc *xb = xi->xi_bus; struct xbridge_intrhandler *xih; - int rc; uint64_t isr; + int rc; +#ifdef MULTIPROCESSOR + int need_lock; +#endif /* XXX shouldn't happen, and assumes interrupt is not shared */ if (LIST_EMPTY(&xi->xi_handlers)) { @@ -1507,10 +1517,22 @@ xbridge_pci_intr_handler(void *v) rc = 0; LIST_FOREACH(xih, &xi->xi_handlers, xih_nxt) { splraise(xih->xih_level); +#ifdef MULTIPROCESSOR + if (ISSET(xih->xih_flags, XIH_MPSAFE)) + need_lock = 0; + else + need_lock = xih->xih_flags < IPL_CLOCK; + if (need_lock) + __mp_lock(&kernel_lock); +#endif if ((*xih->xih_func)(xih->xih_arg) != 0) { xih->xih_count.ec_count++; rc = 1; } +#ifdef MULTIPROCESSOR + if (need_lock) + __mp_unlock(&kernel_lock); +#endif /* * No need to lower spl here, as our caller will * lower spl upon our return. diff --git a/sys/arch/sgi/xbow/xheart.c b/sys/arch/sgi/xbow/xheart.c index cff9b445f2f..babbf7d67ea 100644 --- a/sys/arch/sgi/xbow/xheart.c +++ b/sys/arch/sgi/xbow/xheart.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xheart.c,v 1.30 2016/03/06 19:42:27 mpi Exp $ */ +/* $OpenBSD: xheart.c,v 1.31 2017/02/11 03:44:22 visa Exp $ */ /* * Copyright (c) 2008 Miodrag Vallat. @@ -302,6 +302,7 @@ xheart_intr_establish(int (*func)(void *), void *arg, int intrbit, int level, const char *name, struct intrhand *ihstore) { struct intrhand *ih; + int flags; int s; u_long cpuid = cpu_number(); @@ -310,6 +311,9 @@ xheart_intr_establish(int (*func)(void *), void *arg, int intrbit, return EINVAL; #endif + flags = (level & IPL_MPSAFE) ? IH_MPSAFE : 0; + level &= ~IPL_MPSAFE; + /* * HEART interrupts are not supposed to be shared - the interrupt * mask is large enough for all widgets. @@ -321,17 +325,16 @@ xheart_intr_establish(int (*func)(void *), void *arg, int intrbit, ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT); if (ih == NULL) return ENOMEM; - ih->ih_flags = IH_ALLOCATED; - } else { + flags |= IH_ALLOCATED; + } else ih = ihstore; - ih->ih_flags = 0; - } ih->ih_next = NULL; ih->ih_fun = func; ih->ih_arg = arg; ih->ih_level = level; ih->ih_irq = intrbit; + ih->ih_flags = flags; if (name != NULL) evcount_attach(&ih->ih_count, name, &ih->ih_level); |