From 521b6d5ed6d0633e343be800c3599f0a5e72217a Mon Sep 17 00:00:00 2001 From: Artur Grabowski Date: Wed, 15 May 2002 23:17:55 +0000 Subject: 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. --- sys/arch/sparc/include/psl.h | 36 +++++++++++++++++++++++++++--------- sys/arch/sparc/sparc/intr.c | 17 ++++++++++++++++- 2 files changed, 43 insertions(+), 10 deletions(-) (limited to 'sys/arch') 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); + } +} -- cgit v1.2.3