Subject: kernel stack overflow on netbsd-1-6 branch
To: None <port-i386@netbsd.org>
From: SAITOH Masanobu <masanobu@iij.ad.jp>
List: port-i386
Date: 11/26/2002 19:46:21
Following patches pullup the KSTACK_CHECK_DR0 functions into netbsd-1-6
branch. You may see "trap on DR0: maybe kernel stack overflow" message
at boot time or heavy load.
Should we increase UPAGES or am I misunderstanding something?
Index: conf/files.i386
===================================================================
RCS file: /cvsroot/test/src/sys/arch/i386/conf/files.i386,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 files.i386
--- conf/files.i386 2002/10/10 12:09:27 1.1.1.1
+++ conf/files.i386 2002/11/26 09:49:33
@@ -57,11 +57,14 @@
# Large page size
defflag LARGEPAGES
+# kernel stack debug
+defflag opt_kstack_dr0.h KSTACK_CHECK_DR0
+
file arch/i386/i386/autoconf.c
file arch/i386/i386/bus_machdep.c
file arch/i386/i386/conf.c
file arch/i386/i386/consinit.c
-file arch/i386/i386/db_dbgreg.s ddb
+file arch/i386/i386/db_dbgreg.s ddb | kstack_check_dr0
file arch/i386/i386/db_disasm.c ddb
file arch/i386/i386/db_interface.c ddb
file arch/i386/i386/db_memrw.c ddb | kgdb
Index: i386/pmap.c
===================================================================
RCS file: /cvsroot/test/src/sys/arch/i386/i386/pmap.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 pmap.c
--- i386/pmap.c 2002/10/10 12:09:27 1.1.1.1
+++ i386/pmap.c 2002/11/26 09:49:33
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.136 2002/03/27 04:47:28 chs Exp $ */
+/* $NetBSD: pmap.c,v 1.137 2002/07/03 02:46:13 yamt Exp $ */
/*
*
@@ -60,11 +60,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.136 2002/03/27 04:47:28 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.137 2002/07/03 02:46:13 yamt Exp $");
#include "opt_cputype.h"
#include "opt_user_ldt.h"
#include "opt_largepages.h"
+#include "opt_kstack_dr0.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -1675,6 +1676,16 @@
lcr3(pcb->pcb_cr3);
if (pcb == curpcb)
lldt(pcb->pcb_ldt_sel);
+
+#ifdef KSTACK_CHECK_DR0
+ /*
+ * setup breakpoint on the top of stack
+ */
+ if (p == &proc0)
+ dr0(0, 0, 0, 0);
+ else
+ dr0(KSTACK_LOWEST_ADDR(p), 1, 3, 1);
+#endif
}
/*
Index: i386/trap.c
===================================================================
RCS file: /cvsroot/test/src/sys/arch/i386/i386/trap.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 trap.c
--- i386/trap.c 2002/10/10 12:09:28 1.1.1.1
+++ i386/trap.c 2002/11/26 09:49:33
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.165 2002/02/18 15:58:02 simonb Exp $ */
+/* $NetBSD: trap.c,v 1.166 2002/07/03 02:46:15 yamt Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -79,13 +79,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.165 2002/02/18 15:58:02 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.166 2002/07/03 02:46:15 yamt Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_math_emulate.h"
#include "opt_vm86.h"
#include "opt_cputype.h"
+#include "opt_kstack_dr0.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -202,6 +203,21 @@
default:
we_re_toast:
+#ifdef KSTACK_CHECK_DR0
+ if (type == T_TRCTRAP) {
+ u_int mask, dr6 = rdr6();
+
+ mask = 1 << 0; /* dr0 */
+ if (dr6 & mask) {
+ panic("trap on DR0: maybe kernel stack overflow\n");
+#if 0
+ dr6 &= ~mask;
+ ldr6(dr6);
+ return;
+#endif
+ }
+ }
+#endif
#ifdef KGDB
if (kgdb_trap(type, &frame))
return;
Index: include/cpufunc.h
===================================================================
RCS file: /cvsroot/test/src/sys/arch/i386/include/cpufunc.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 cpufunc.h
--- include/cpufunc.h 2002/10/10 12:09:28 1.1.1.1
+++ include/cpufunc.h 2002/11/26 09:49:33
@@ -1,4 +1,4 @@
-/* $NetBSD: cpufunc.h,v 1.20 2001/07/31 18:28:59 thorpej Exp $ */
+/* $NetBSD: cpufunc.h,v 1.21 2002/07/03 02:46:16 yamt Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -134,6 +134,24 @@
void setidt __P((int idx, /*XXX*/caddr_t func, int typ, int dpl));
#endif
+/* debug register */
+void dr0(caddr_t, u_int32_t, u_int32_t, u_int32_t);
+
+static __inline u_int
+rdr6(void)
+{
+ u_int val;
+
+ __asm __volatile("movl %%dr6,%0" : "=r" (val));
+ return val;
+}
+
+static __inline void
+ldr6(u_int val)
+{
+
+ __asm __volatile("movl %0,%%dr6" : : "r" (val));
+}
/* XXXX ought to be in psl.h with spl() functions */
Index: include/proc.h
===================================================================
RCS file: /cvsroot/test/src/sys/arch/i386/include/proc.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 proc.h
--- include/proc.h 2002/10/10 12:09:28 1.1.1.1
+++ include/proc.h 2002/11/26 09:49:33
@@ -1,4 +1,4 @@
-/* $NetBSD: proc.h,v 1.14 2001/09/10 10:11:21 fvdl Exp $ */
+/* $NetBSD: proc.h,v 1.15 2002/10/11 17:49:11 yamt Exp $ */
/*
* Copyright (c) 1991 Regents of the University of California.
@@ -51,3 +51,12 @@
/* md_flags */
#define MDP_USEDFPU 0x0001 /* has used the FPU */
#define MDP_USEDMTRR 0x0002 /* has set volatile MTRRs */
+
+/* kernel stack params */
+#ifndef NOREDZONE
+/* override default for redzone */
+#define KSTACK_LOWEST_ADDR(p) \
+ ((caddr_t)ALIGN((p)->p_addr + 1) + NBPG)
+#define KSTACK_SIZE \
+ (USPACE - NBPG*2)
+#endif