diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-05-15 23:17:55 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-05-15 23:17:55 +0000 |
commit | 521b6d5ed6d0633e343be800c3599f0a5e72217a (patch) | |
tree | 02e3dd3e7b165d038303bd07ba57717af4db0454 /sys | |
parent | 33bc70fe0c79cdb72d78b3044cf69a275b11a3b0 (diff) |
Implement splassert() for sparc - a tool for finding problems related to
spl handling (already found 3 problems).
Man page in a few seconds.
deraadt@ ok.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc/include/psl.h | 36 | ||||
-rw-r--r-- | sys/arch/sparc/sparc/intr.c | 17 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 5 | ||||
-rw-r--r-- | sys/kern/subr_prf.c | 25 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 6 | ||||
-rw-r--r-- | sys/sys/systm.h | 5 |
6 files changed, 79 insertions, 15 deletions
diff --git a/sys/arch/sparc/include/psl.h b/sys/arch/sparc/include/psl.h index 556559353f9..a673d5fa37e 100644 --- a/sys/arch/sparc/include/psl.h +++ b/sys/arch/sparc/include/psl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: psl.h,v 1.12 2002/04/30 01:03:04 art Exp $ */ +/* $OpenBSD: psl.h,v 1.13 2002/05/15 23:17:54 art Exp $ */ /* $NetBSD: psl.h,v 1.12 1997/03/10 21:49:11 pk Exp $ */ /* @@ -107,13 +107,11 @@ static __inline int splhigh(void); static __inline void splx(int); static __inline int getmid(void); -/* SPL asserts */ -#define splassert(wantipl) /* nothing */ - /* * GCC pseudo-functions for manipulating PSR (primarily PIL field). */ -static __inline int getpsr() +static __inline int +getpsr() { int psr; @@ -121,7 +119,8 @@ static __inline int getpsr() return (psr); } -static __inline int getmid() +static __inline int +getmid() { int mid; @@ -129,7 +128,8 @@ static __inline int getmid() return ((mid >> 20) & 0x3); } -static __inline void setpsr(newpsr) +static __inline void +setpsr(newpsr) int newpsr; { __asm __volatile("wr %0,0,%%psr" : : "r" (newpsr)); @@ -138,7 +138,8 @@ static __inline void setpsr(newpsr) __asm __volatile("nop"); } -static __inline int spl0() +static __inline int +spl0() { int psr, oldipl; @@ -159,6 +160,23 @@ static __inline int spl0() return (oldipl); } +#ifdef DIAGNOSTIC +/* + * Although this function is implemented in MI code, it must be in this MD + * header because we don't want this header to include MI includes. + */ +void splassert_fail(int, int, const char *); +extern int splassert_ctl; +void splassert_check(int, const char *); +#define splassert(__wantipl) do { \ + if (__predict_false(splassert_ctl > 0)) { \ + splassert_check(__wantipl, __func__); \ + } \ +} while (0) +#else +#define splassert(wantipl) do { /* nada */ } while (0) +#endif + /* * PIL 1 through 14 can use this macro. * (spl0 and splhigh are special since they put all 0s or all 1s @@ -166,7 +184,7 @@ static __inline int spl0() */ #define SPL(name, newipl) \ static __inline int name(void); \ - static __inline int name() \ +static __inline int name() \ { \ int psr, oldipl; \ __asm __volatile("rd %%psr,%0" : "=r" (psr)); \ diff --git a/sys/arch/sparc/sparc/intr.c b/sys/arch/sparc/sparc/intr.c index 24e92b62f38..1dc8a42a81c 100644 --- a/sys/arch/sparc/sparc/intr.c +++ b/sys/arch/sparc/sparc/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.19 2002/04/30 01:12:28 art Exp $ */ +/* $OpenBSD: intr.c,v 1.20 2002/05/15 23:17:54 art Exp $ */ /* $NetBSD: intr.c,v 1.20 1997/07/29 09:42:03 fair Exp $ */ /* @@ -365,3 +365,18 @@ intr_fasttrap(level, vec) pmap_writetext(tvp, *instrp); splx(s); } + +void +splassert_check(int wantipl, const char *func) +{ + int oldipl = (getpsr() & PSR_PIL) >> 8; + + if (oldipl < wantipl) { + splassert_fail(wantipl, oldipl, func); + /* + * If the splassert_ctl is set to not panic, raise the ipl + * in a feeble attempt to reduce damage. + */ + setpsr((getpsr() & ~PSR_PIL) | wantipl << 8); + } +} diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 99b50f6d300..d56f03df0f7 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.64 2002/03/14 20:31:31 mickey Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.65 2002/05/15 23:17:53 art Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -433,6 +433,9 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) return (sysctl_int(oldp, oldlenp, newp, newlen, &cryptodevallowsoft)); #endif + case KERN_SPLASSERT: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &splassert_ctl)); default: return (EOPNOTSUPP); } diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index b15cb472739..2a20170da5e 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prf.c,v 1.40 2002/03/15 18:19:52 millert Exp $ */ +/* $OpenBSD: subr_prf.c,v 1.41 2002/05/15 23:17:53 art Exp $ */ /* $NetBSD: subr_prf.c,v 1.45 1997/10/24 18:14:25 chuck Exp $ */ /*- @@ -131,6 +131,11 @@ int db_console = 0; #endif /* + * panic on spl assertion failure? + */ +int splassert_ctl = 0; + +/* * v_putc: routine to putc on virtual console * * the v_putc pointer can be used to redirect the console cnputc elsewhere @@ -219,6 +224,24 @@ panic(const char *fmt, ...) } /* + * We print only the function name. The file name is usually very long and + * would eat tons of space in the kernel. + */ +void +splassert_fail(int wantipl, int haveipl, const char *func) +{ + + printf("splassert: %s: want %d have %d\n", func, wantipl, haveipl); + if (splassert_ctl > 1) { + panic("spl assertion failure in %s", func); + } else { +#ifdef DDB + /* Will print stack trace RSN. */ +#endif + } +} + +/* * kernel logging functions: log, logpri, addlog */ diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 12123791f10..f87efe46679 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.48 2002/03/14 19:42:54 mickey Exp $ */ +/* $OpenBSD: sysctl.h,v 1.49 2002/05/15 23:17:53 art Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -167,7 +167,8 @@ struct ctlname { #define KERN_SYSVIPC_INFO 51 /* struct: SysV sem/shm/msg info */ #define KERN_USERCRYPTO 52 /* int: usercrypto */ #define KERN_CRYPTODEVALLOWSOFT 53 /* int: cryptodevallowsoft */ -#define KERN_MAXID 54 /* number of valid kern ids */ +#define KERN_SPLASSERT 54 /* int: splassert */ +#define KERN_MAXID 55 /* number of valid kern ids */ #define CTL_KERN_NAMES { \ { 0, 0 }, \ @@ -224,6 +225,7 @@ struct ctlname { { "sysvipc_info", CTLTYPE_INT }, \ { "usercrypto", CTLTYPE_INT }, \ { "cryptodevallowsoft", CTLTYPE_INT }, \ + { "splassert", CTLTYPE_INT }, \ } /* diff --git a/sys/sys/systm.h b/sys/sys/systm.h index b78d46a638f..e46f17a0a99 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systm.h,v 1.49 2002/03/14 20:31:31 mickey Exp $ */ +/* $OpenBSD: systm.h,v 1.50 2002/05/15 23:17:53 art Exp $ */ /* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */ /*- @@ -182,6 +182,9 @@ struct tty; void ttyprintf(struct tty *, const char *, ...) __kprintf_attribute__((__format__(__kprintf__,2,3))); +void splassert_fail(int, int, const char *); +extern int splassert_ctl; + void tablefull(const char *); int kcopy(const void *, void *, size_t); |