summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sgi/include/intr.h5
-rw-r--r--sys/arch/sgi/localbus/int.c5
-rw-r--r--sys/arch/sgi/localbus/macebus.c5
-rw-r--r--sys/arch/sgi/sgi/intr_template.c19
-rw-r--r--sys/arch/sgi/sgi/ip27_machdep.c13
-rw-r--r--sys/arch/sgi/xbow/xbridge.c30
-rw-r--r--sys/arch/sgi/xbow/xheart.c13
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);