when we're entering an interrupt handler, record its ipl so splassert
authordlg <dlg@openbsd.org>
Tue, 6 Jan 2015 12:50:47 +0000 (12:50 +0000)
committerdlg <dlg@openbsd.org>
Tue, 6 Jan 2015 12:50:47 +0000 (12:50 +0000)
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@

sys/arch/amd64/amd64/acpi_machdep.c
sys/arch/amd64/amd64/cpu.c
sys/arch/amd64/amd64/intr.c
sys/arch/amd64/amd64/ipi.c
sys/arch/amd64/amd64/lapic.c
sys/arch/amd64/amd64/machdep.c
sys/arch/amd64/amd64/softintr.c
sys/arch/amd64/include/cpu.h

index 25b3fbb..2b641b9 100644 (file)
@@ -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);
index b76e7fc..6bebf80 100644 (file)
@@ -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)
        /*
index 8f4d4dd..fb19dad 100644 (file)
@@ -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);
index 48090bb..7894356 100644 (file)
@@ -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;
 }
index 41cf4bf..bf8a021 100644 (file)
@@ -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++;
 }
index 53402f7..fcf0482 100644 (file)
@@ -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
 
index 3b50c59..67ec891 100644 (file)
@@ -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;
 }
 
 /*
index 3f815e5..b06d58b 100644 (file)
@@ -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