summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-01-06 12:50:49 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-01-06 12:50:49 +0000
commit9dddce030eb87a866b16bd155ed927c34dec06d8 (patch)
treecf509cf80051cced9aa3165ba0c7c95141019d07 /sys
parentcb240f2325fc8b0923d29bb6e5ad09aa0dc4067c (diff)
when we're entering an interrupt handler, record its ipl so splassert
can check if we're entering code we think should only be used from lower ipls. modelled a bit on how sparc64 does things. with help from and ok kettenis@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/acpi_machdep.c3
-rw-r--r--sys/arch/amd64/amd64/cpu.c3
-rw-r--r--sys/arch/amd64/amd64/intr.c7
-rw-r--r--sys/arch/amd64/amd64/ipi.c9
-rw-r--r--sys/arch/amd64/amd64/lapic.c7
-rw-r--r--sys/arch/amd64/amd64/machdep.c9
-rw-r--r--sys/arch/amd64/amd64/softintr.c9
-rw-r--r--sys/arch/amd64/include/cpu.h3
8 files changed, 38 insertions, 12 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c
index 25b3fbb2b73..2b641b921e6 100644
--- a/sys/arch/amd64/amd64/acpi_machdep.c
+++ b/sys/arch/amd64/amd64/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi_machdep.c,v 1.67 2014/12/18 05:33:48 mlarkin Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.68 2015/01/06 12:50:47 dlg Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -426,6 +426,7 @@ acpi_resume_mp(void)
pcb->pcb_rbp = 0;
ci->ci_idepth = 0;
+ ci->ci_handled_intr_level = IPL_NONE;
ci->ci_flags &= ~CPUF_PRESENT;
cpu_start_secondary(ci);
diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c
index b76e7fc6545..6bebf804076 100644
--- a/sys/arch/amd64/amd64/cpu.c
+++ b/sys/arch/amd64/amd64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.76 2014/12/18 16:23:26 deraadt Exp $ */
+/* $OpenBSD: cpu.c,v 1.77 2015/01/06 12:50:47 dlg Exp $ */
/* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */
/*-
@@ -432,6 +432,7 @@ cpu_attach(struct device *parent, struct device *self, void *aux)
ci->ci_cpuid = 0; /* False for APs, but they're not used anyway */
#endif
ci->ci_func = caa->cpu_func;
+ ci->ci_handled_intr_level = IPL_NONE;
#if defined(MULTIPROCESSOR)
/*
diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c
index 8f4d4dddcdf..fb19dadec3a 100644
--- a/sys/arch/amd64/amd64/intr.c
+++ b/sys/arch/amd64/amd64/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.39 2014/12/02 18:13:10 tedu Exp $ */
+/* $OpenBSD: intr.c,v 1.40 2015/01/06 12:50:47 dlg Exp $ */
/* $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $ */
/*
@@ -514,6 +514,8 @@ intr_disestablish(struct intrhand *ih)
int
intr_handler(struct intrframe *frame, struct intrhand *ih)
{
+ struct cpu_info *ci = curcpu();
+ int floor;
int rc;
#ifdef MULTIPROCESSOR
int need_lock;
@@ -526,7 +528,10 @@ intr_handler(struct intrframe *frame, struct intrhand *ih)
if (need_lock)
__mp_lock(&kernel_lock);
#endif
+ floor = ci->ci_handled_intr_level;
+ ci->ci_handled_intr_level = ih->ih_level;
rc = (*ih->ih_fun)(ih->ih_arg ? ih->ih_arg : frame);
+ ci->ci_handled_intr_level = floor;
#ifdef MULTIPROCESSOR
if (need_lock)
__mp_unlock(&kernel_lock);
diff --git a/sys/arch/amd64/amd64/ipi.c b/sys/arch/amd64/amd64/ipi.c
index 48090bb79da..7894356fda9 100644
--- a/sys/arch/amd64/amd64/ipi.c
+++ b/sys/arch/amd64/amd64/ipi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipi.c,v 1.12 2015/01/06 00:38:32 dlg Exp $ */
+/* $OpenBSD: ipi.c,v 1.13 2015/01/06 12:50:47 dlg Exp $ */
/* $NetBSD: ipi.c,v 1.2 2003/03/01 13:05:37 fvdl Exp $ */
/*-
@@ -102,9 +102,12 @@ x86_ipi_handler(void)
struct cpu_info *ci = curcpu();
u_int32_t pending;
int bit;
+ int floor;
- pending = atomic_swap_uint(&ci->ci_ipis, 0);
+ floor = ci->ci_handled_intr_level;
+ ci->ci_handled_intr_level = ci->ci_ilevel;
+ pending = atomic_swap_uint(&ci->ci_ipis, 0);
for (bit = 0; bit < X86_NIPI && pending; bit++) {
if (pending & (1<<bit)) {
pending &= ~(1<<bit);
@@ -112,4 +115,6 @@ x86_ipi_handler(void)
ipi_count.ec_count++;
}
}
+
+ ci->ci_handled_intr_level = floor;
}
diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c
index 41cf4bf4fc0..bf8a0217967 100644
--- a/sys/arch/amd64/amd64/lapic.c
+++ b/sys/arch/amd64/amd64/lapic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lapic.c,v 1.36 2014/12/18 05:33:48 mlarkin Exp $ */
+/* $OpenBSD: lapic.c,v 1.37 2015/01/06 12:50:47 dlg Exp $ */
/* $NetBSD: lapic.c,v 1.2 2003/05/08 01:04:35 fvdl Exp $ */
/*-
@@ -272,8 +272,13 @@ u_int32_t lapic_delaytab[26];
void
lapic_clockintr(void *arg, struct intrframe frame)
{
+ struct cpu_info *ci = curcpu();
+ int floor;
+ floor = ci->ci_handled_intr_level;
+ ci->ci_handled_intr_level = ci->ci_ilevel;
hardclock((struct clockframe *)&frame);
+ ci->ci_handled_intr_level = floor;
clk_count.ec_count++;
}
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 53402f706fb..fcf04826732 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.204 2014/12/21 16:27:07 mlarkin Exp $ */
+/* $OpenBSD: machdep.c,v 1.205 2015/01/06 12:50:47 dlg Exp $ */
/* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */
/*-
@@ -1774,14 +1774,15 @@ void
splassert_check(int wantipl, const char *func)
{
int cpl = curcpu()->ci_ilevel;
+ int floor = curcpu()->ci_handled_intr_level;
if (cpl < wantipl) {
splassert_fail(wantipl, cpl, func);
}
-
- if (wantipl == IPL_NONE && curcpu()->ci_idepth != 0) {
- splassert_fail(-1, curcpu()->ci_idepth, func);
+ if (floor > wantipl) {
+ splassert_fail(wantipl, floor, func);
}
+
}
#endif
diff --git a/sys/arch/amd64/amd64/softintr.c b/sys/arch/amd64/amd64/softintr.c
index 3b50c59b556..67ec8919718 100644
--- a/sys/arch/amd64/amd64/softintr.c
+++ b/sys/arch/amd64/amd64/softintr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softintr.c,v 1.6 2014/07/12 18:44:41 tedu Exp $ */
+/* $OpenBSD: softintr.c,v 1.7 2015/01/06 12:50:48 dlg Exp $ */
/* $NetBSD: softintr.c,v 1.1 2003/02/26 21:26:12 fvdl Exp $ */
/*-
@@ -76,8 +76,13 @@ softintr_init(void)
void
softintr_dispatch(int which)
{
+ struct cpu_info *ci = curcpu();
struct x86_soft_intr *si = &x86_soft_intrs[which];
struct x86_soft_intrhand *sih;
+ int floor;
+
+ floor = ci->ci_handled_intr_level;
+ ci->ci_handled_intr_level = ci->ci_ilevel;
for (;;) {
mtx_enter(&si->softintr_lock);
@@ -95,6 +100,8 @@ softintr_dispatch(int which)
(*sih->sih_fn)(sih->sih_arg);
}
+
+ ci->ci_handled_intr_level = floor;
}
/*
diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h
index 3f815e557b5..b06d58bc096 100644
--- a/sys/arch/amd64/include/cpu.h
+++ b/sys/arch/amd64/include/cpu.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.88 2014/12/16 21:20:23 tedu Exp $ */
+/* $OpenBSD: cpu.h,v 1.89 2015/01/06 12:50:48 dlg Exp $ */
/* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */
/*-
@@ -85,6 +85,7 @@ struct cpu_info {
u_int64_t ci_ipending;
int ci_ilevel;
int ci_idepth;
+ int ci_handled_intr_level;
u_int64_t ci_imask[NIPL];
u_int64_t ci_iunmask[NIPL];
#ifdef DIAGNOSTIC