From 9c9e7f9589640a9e5361bdda14b2fbff60e024b2 Mon Sep 17 00:00:00 2001 From: dlg Date: Tue, 6 Jan 2015 12:50:47 +0000 Subject: [PATCH] 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@ --- sys/arch/amd64/amd64/acpi_machdep.c | 3 ++- sys/arch/amd64/amd64/cpu.c | 3 ++- sys/arch/amd64/amd64/intr.c | 7 ++++++- sys/arch/amd64/amd64/ipi.c | 9 +++++++-- sys/arch/amd64/amd64/lapic.c | 7 ++++++- sys/arch/amd64/amd64/machdep.c | 9 +++++---- sys/arch/amd64/amd64/softintr.c | 9 ++++++++- sys/arch/amd64/include/cpu.h | 3 ++- 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 * @@ -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<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 -- 2.20.1