summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-05-15 23:17:55 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-05-15 23:17:55 +0000
commit521b6d5ed6d0633e343be800c3599f0a5e72217a (patch)
tree02e3dd3e7b165d038303bd07ba57717af4db0454 /sys
parent33bc70fe0c79cdb72d78b3044cf69a275b11a3b0 (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.h36
-rw-r--r--sys/arch/sparc/sparc/intr.c17
-rw-r--r--sys/kern/kern_sysctl.c5
-rw-r--r--sys/kern/subr_prf.c25
-rw-r--r--sys/sys/sysctl.h6
-rw-r--r--sys/sys/systm.h5
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);