Module Name:    src
Committed By:   rmind
Date:           Wed Jul 29 18:47:15 UTC 2009

Modified Files:
        src/sys/arch/amd64/amd64: trap.c
        src/sys/arch/i386/i386: trap.c

Log Message:
Reduce the difference between i386 and amd64 trap handler.
No functional changes intended.


To generate a diff of this commit:
cvs rdiff -u -r1.58 -r1.59 src/sys/arch/amd64/amd64/trap.c
cvs rdiff -u -r1.246 -r1.247 src/sys/arch/i386/i386/trap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/amd64/trap.c
diff -u src/sys/arch/amd64/amd64/trap.c:1.58 src/sys/arch/amd64/amd64/trap.c:1.59
--- src/sys/arch/amd64/amd64/trap.c:1.58	Wed Jul 29 17:14:38 2009
+++ src/sys/arch/amd64/amd64/trap.c	Wed Jul 29 18:47:15 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: trap.c,v 1.58 2009/07/29 17:14:38 rmind Exp $	*/
+/*	$NetBSD: trap.c,v 1.59 2009/07/29 18:47:15 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.58 2009/07/29 17:14:38 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.59 2009/07/29 18:47:15 rmind Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -81,12 +81,12 @@
 #include <sys/acct.h>
 #include <sys/kauth.h>
 #include <sys/kernel.h>
+#include <sys/pool.h>
+#include <sys/ras.h>
 #include <sys/signal.h>
 #include <sys/syscall.h>
-#include <sys/ras.h>
-#include <sys/reboot.h>
-#include <sys/pool.h>
 #include <sys/cpu.h>
+#include <sys/ucontext.h>
 #include <sys/sa.h>
 #include <sys/savar.h>
 
@@ -114,7 +114,7 @@
 
 void trap(struct trapframe *);
 
-const char *trap_type[] = {
+const char * const trap_type[] = {
 	"privileged instruction fault",		/*  0 T_PRIVINFLT */
 	"breakpoint trap",			/*  1 T_BPTFLT */
 	"arithmetic trap",			/*  2 T_ARITHTRAP */
@@ -133,11 +133,11 @@
 	"invalid TSS fault",			/* 15 T_TSSFLT */
 	"segment not present fault",		/* 16 T_SEGNPFLT */
 	"stack fault",				/* 17 T_STKFLT */
-	"machine check",			/* 18 T_MCA */
+	"machine check fault",			/* 18 T_MCA */
 	"SSE FP exception",			/* 19 T_XMM */
 	"reserved trap",			/* 20 T_RESERVED */
 };
-int	trap_types = sizeof trap_type / sizeof trap_type[0];
+int	trap_types = __arraycount(trap_type);
 
 #ifdef DEBUG
 int	trapdebug = 0;
@@ -177,20 +177,18 @@
 }
 
 /*
- * trap(frame):
- *	Exception, fault, and trap interface to BSD kernel. This
- * common code is called from assembly language IDT gate entry
- * routines that prepare a suitable stack frame, and restore this
- * frame after the exception has been processed. Note that the
- * effect is as if the arguments were passed call by reference.
+ * trap(frame): exception, fault, and trap interface to BSD kernel.
+ *
+ * This common code is called from assembly language IDT gate entry routines
+ * that prepare a suitable stack frame, and restore this frame after the
+ * exception has been processed. Note that the effect is as if the arguments
+ * were passed call by reference.
  */
-/*ARGSUSED*/
 void
 trap(struct trapframe *frame)
 {
 	struct lwp *l = curlwp;
 	struct proc *p;
-	int type = (int)frame->tf_trapno;
 	struct pcb *pcb;
 	extern char fusuintrfailure[], kcopy_fault[],
 		    resume_iret[];
@@ -199,11 +197,11 @@
 	extern char resume_pop_ds[], resume_pop_es[];
 #endif
 	struct trapframe *vframe;
+	ksiginfo_t ksi;
 	void *resume;
 	void *onfault;
-	int error;
+	int type, error;
 	uint64_t cr2;
-	ksiginfo_t ksi;
 	bool pfail;
 
 	if (__predict_true(l != NULL)) {
@@ -216,18 +214,19 @@
 		pcb = NULL;
 		p = NULL;
 	}
+	type = frame->tf_trapno;
+
 #ifdef DEBUG
 	if (trapdebug) {
 		printf("trap %d code %lx eip %lx cs %lx rflags %lx cr2 %lx "
 		       "cpl %x\n",
 		    type, frame->tf_err, frame->tf_rip, frame->tf_cs,
 		    frame->tf_rflags, rcr2(), curcpu()->ci_ilevel);
-		printf("curlwp %p\n", curlwp);
+		printf("curlwp %p%s", curlwp, curlwp ? " " : "\n");
 		if (curlwp)
 			printf("pid %d lid %d\n", l->l_proc->p_pid, l->l_lid);
 	}
 #endif
-
 	if (type != T_NMI && !KERNELMODE(frame->tf_cs, frame->tf_rflags)) {
 		type |= T_USER;
 		l->l_md.md_regs = frame;
@@ -247,6 +246,10 @@
 		       " %lx cpl %x rsp %lx\n",
 		    type, frame->tf_err, (u_long)frame->tf_rip, frame->tf_cs,
 		    frame->tf_rflags, rcr2(), curcpu()->ci_ilevel, frame->tf_rsp);
+#ifdef DDB
+		if (kdb_trap(type, 0, frame))
+			return;
+#endif
 #ifdef KGDB
 		if (kgdb_trap(type, frame))
 			return;
@@ -261,10 +264,6 @@
 			}
 		}
 #endif
-#ifdef DDB
-		if (kdb_trap(type, 0, frame))
-			return;
-#endif
 		panic("trap");
 		/*NOTREACHED*/
 
@@ -364,9 +363,7 @@
 			ksi.ksi_code = SEGV_ACCERR;
 			break;
 		default:
-#ifdef DIAGNOSTIC
-			panic("unhandled type %x\n", type);
-#endif
+			KASSERT(0);
 			break;
 		}
 		goto trapsignal;
@@ -390,9 +387,7 @@
 			ksi.ksi_code = ILL_COPROC;
 			break;
 		default:
-#ifdef DIAGNOSTIC
-			panic("unhandled type %x\n", type);
-#endif
+			KASSERT(0);
 			break;
 		}
 		goto trapsignal;
@@ -408,8 +403,9 @@
 			ADDUPROF(l);
 		}
 		/* Allow a forced task switch. */
-		if (curcpu()->ci_want_resched)
+		if (curcpu()->ci_want_resched) {
 			preempt();
+		}
 		goto out;
 
 #if 0 /* handled by fpudna() */
@@ -447,9 +443,11 @@
 		}
 		goto trapsignal;
 
-	case T_PAGEFLT:			/* allow page faults in kernel mode */
-		if (l == NULL)
+	case T_PAGEFLT:
+		/* Allow page faults in kernel mode. */
+		if (__predict_false(l == NULL))
 			goto we_re_toast;
+
 		/*
 		 * fusuintrfailure is used by [fs]uswintr() to prevent
 		 * page faulting from inside the profiling interrupt.
@@ -482,8 +480,9 @@
 		}
 faultcommon:
 		vm = p->p_vmspace;
-		if (vm == NULL)
+		if (__predict_false(vm == NULL)) {
 			goto we_re_toast;
+		}
 		pcb->pcb_cr2 = cr2;
 		va = trunc_page((vaddr_t)cr2);
 		/*
@@ -511,7 +510,6 @@
 			goto we_re_toast;
 		}
 #endif
-
 		/* Fault the original page in. */
 		onfault = pcb->pcb_onfault;
 		pcb->pcb_onfault = NULL;
@@ -573,12 +571,13 @@
 		}
 		KSI_INIT_TRAP(&ksi);
 		ksi.ksi_trap = type & ~T_USER;
-		ksi.ksi_addr = (void *)rcr2();
+		ksi.ksi_addr = (void *)cr2;
 		if (error == EACCES) {
 			ksi.ksi_code = SEGV_ACCERR;
 			error = EFAULT;
-		} else
+		} else {
 			ksi.ksi_code = SEGV_MAPERR;
+		}
 
 		if (type == T_PAGEFLT) {
 			onfault = onfault_handler(pcb, frame);
@@ -619,6 +618,9 @@
 
 	case T_BPTFLT|T_USER:		/* bpt instruction fault */
 	case T_TRCTRAP|T_USER:		/* trace trap */
+		/*
+		 * Don't go single-stepping into a RAS.
+		 */
 		if (p->p_raslist == NULL ||
 		    (ras_lookup(p, (void *)frame->tf_rip) == (void *)-1)) {
 			KSI_INIT_TRAP(&ksi);
@@ -671,23 +673,29 @@
 	userret(l);
 }
 
+/* 
+ * startlwp: start of a new LWP.
+ */
 void
 startlwp(void *arg)
 {
-	int err;
 	ucontext_t *uc = arg;
-	struct lwp *l = curlwp;
+	lwp_t *l = curlwp;
+	int error;
 
-	err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
+	error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
+	KASSERT(error == 0);
 	pool_put(&lwp_uc_pool, uc);
 	userret(l);
 }
 
+/*
+ * XXX_SA: This is a terrible name.
+ */
 void
 upcallret(struct lwp *l)
 {
 	KERNEL_UNLOCK_LAST(l);
-
 	userret(l);
 }
 

Index: src/sys/arch/i386/i386/trap.c
diff -u src/sys/arch/i386/i386/trap.c:1.246 src/sys/arch/i386/i386/trap.c:1.247
--- src/sys/arch/i386/i386/trap.c:1.246	Wed Jul 29 17:16:56 2009
+++ src/sys/arch/i386/i386/trap.c	Wed Jul 29 18:47:15 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: trap.c,v 1.246 2009/07/29 17:16:56 rmind Exp $	*/
+/*	$NetBSD: trap.c,v 1.247 2009/07/29 18:47:15 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.246 2009/07/29 17:16:56 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.247 2009/07/29 18:47:15 rmind Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -82,14 +82,14 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
-#include <sys/pool.h>
 #include <sys/user.h>
 #include <sys/acct.h>
+#include <sys/kauth.h>
 #include <sys/kernel.h>
+#include <sys/pool.h>
 #include <sys/ras.h>
 #include <sys/signal.h>
 #include <sys/syscall.h>
-#include <sys/kauth.h>
 #include <sys/cpu.h>
 #include <sys/ucontext.h>
 #include <sys/sa.h>
@@ -224,7 +224,7 @@
 	case 0:
 	default:
 		return 0;
-        }
+	}
 }
 
 static void *
@@ -253,26 +253,24 @@
 }
 
 /*
- * trap(frame):
- *	Exception, fault, and trap interface to BSD kernel. This
- * common code is called from assembly language IDT gate entry
- * routines that prepare a suitable stack frame, and restore this
- * frame after the exception has been processed. Note that the
- * effect is as if the arguments were passed call by reference.
+ * trap(frame): exception, fault, and trap interface to BSD kernel.
+ *
+ * This common code is called from assembly language IDT gate entry routines
+ * that prepare a suitable stack frame, and restore this frame after the
+ * exception has been processed. Note that the effect is as if the arguments
+ * were passed call by reference.
  */
-/*ARGSUSED*/
 void
 trap(struct trapframe *frame)
 {
 	struct lwp *l = curlwp;
 	struct proc *p;
-	int type = frame->tf_trapno;
 	struct pcb *pcb;
 	extern char fusubail[], kcopy_fault[], trapreturn[], IDTVEC(osyscall)[];
 	struct trapframe *vframe;
 	ksiginfo_t ksi;
 	void *onfault;
-	int error;
+	int type, error;
 	uint32_t cr2;
 	bool pfail;
 
@@ -286,17 +284,18 @@
 		pcb = NULL;
 		p = NULL;
 	}
+	type = frame->tf_trapno;
+
 #ifdef DEBUG
 	if (trapdebug) {
 		printf("trap %d code %x eip %x cs %x eflags %x cr2 %lx cpl %x\n",
-		    frame->tf_trapno, frame->tf_err, frame->tf_eip, frame->tf_cs,
+		    type, frame->tf_err, frame->tf_eip, frame->tf_cs,
 		    frame->tf_eflags, rcr2(), curcpu()->ci_ilevel);
 		printf("curlwp %p%s", curlwp, curlwp ? " " : "\n");
 		if (curlwp)
 			printf("pid %d lid %d\n", l->l_proc->p_pid, l->l_lid);
 	}
 #endif
-
 	if (type != T_NMI && !KVM86MODE &&
 	    !KERNELMODE(frame->tf_cs, frame->tf_eflags)) {
 		type |= T_USER;
@@ -447,41 +446,45 @@
 		return;
 
 	case T_PROTFLT|T_USER:		/* protection fault */
-#ifdef VM86
-		if (frame->tf_eflags & PSL_VM) {
-			vm86_gpfault(l, type & ~T_USER);
-			goto out;
-		}
-#endif
-		/* If pmap_exec_fixup does something, let's retry the trap. */
-		if (pmap_exec_fixup(&p->p_vmspace->vm_map, frame,
-		    &l->l_addr->u_pcb)) {
-			goto out;
-		}
-		KSI_INIT_TRAP(&ksi);
-		ksi.ksi_signo = SIGSEGV;
-		ksi.ksi_addr = (void *)rcr2();
-		ksi.ksi_code = SEGV_ACCERR;
-		goto trapsignal;
-
 	case T_TSSFLT|T_USER:
 	case T_SEGNPFLT|T_USER:
 	case T_STKFLT|T_USER:
 	case T_ALIGNFLT|T_USER:
 		KSI_INIT_TRAP(&ksi);
-		ksi.ksi_signo = SIGBUS;
+
 		ksi.ksi_addr = (void *)rcr2();
 		switch (type) {
 		case T_SEGNPFLT|T_USER:
 		case T_STKFLT|T_USER:
+			ksi.ksi_signo = SIGBUS;
 			ksi.ksi_code = BUS_ADRERR;
 			break;
 		case T_TSSFLT|T_USER:
+			ksi.ksi_signo = SIGBUS;
 			ksi.ksi_code = BUS_OBJERR;
 			break;
 		case T_ALIGNFLT|T_USER:
+			ksi.ksi_signo = SIGBUS;
 			ksi.ksi_code = BUS_ADRALN;
 			break;
+		case T_PROTFLT|T_USER:
+#ifdef VM86
+			if (frame->tf_eflags & PSL_VM) {
+				vm86_gpfault(l, type & ~T_USER);
+				goto out;
+			}
+#endif
+			/*
+			 * If pmap_exec_fixup does something,
+			 * let's retry the trap.
+			 */
+			if (pmap_exec_fixup(&p->p_vmspace->vm_map, frame,
+			    &l->l_addr->u_pcb)) {
+				goto out;
+			}
+			ksi.ksi_signo = SIGSEGV;
+			ksi.ksi_code = SEGV_ACCERR;
+			break;
 		default:
 			KASSERT(0);
 			break;
@@ -506,15 +509,17 @@
 		}
 		goto trapsignal;
 
-	case T_ASTFLT|T_USER:		/* Allow process switch */
+	case T_ASTFLT|T_USER:
+		/* Allow process switch. */
 		uvmexp.softs++;
 		if (l->l_pflag & LP_OWEUPC) {
 			l->l_pflag &= ~LP_OWEUPC;
 			ADDUPROF(l);
 		}
 		/* Allow a forced task switch. */
-		if (curcpu()->ci_want_resched)
+		if (curcpu()->ci_want_resched) {
 			preempt();
+		}
 		goto out;
 
 	case T_DNA|T_USER: {
@@ -554,15 +559,17 @@
 		}
 		goto trapsignal;
 
-	case T_PAGEFLT:			/* allow page faults in kernel mode */
-		if (l == 0)
+	case T_PAGEFLT:
+		/* Allow page faults in kernel mode. */
+		if (__predict_false(l == NULL))
 			goto we_re_toast;
 
 		/*
 		 * fusubail is used by [fs]uswintr() to prevent page faulting
 		 * from inside the profiling interrupt.
 		 */
-		if ((onfault = pcb->pcb_onfault) == fusubail) {
+		onfault = pcb->pcb_onfault;
+		if (onfault == fusubail) {
 			goto copyefault;
 		}
 		if (cpu_intr_p() || (l->l_pflag & LP_INTR) != 0) {
@@ -584,12 +591,13 @@
 			l->l_savp->savp_faultaddr = (vaddr_t)cr2;
 			l->l_pflag |= LP_SA_PAGEFAULT;
 		}
-	faultcommon:
+faultcommon:
 		vm = p->p_vmspace;
-		if (vm == NULL)
+		if (__predict_false(vm == NULL)) {
 			goto we_re_toast;
+		}
 		pcb->pcb_cr2 = cr2;
-		va = trunc_page((vaddr_t)pcb->pcb_cr2);
+		va = trunc_page((vaddr_t)cr2);
 		/*
 		 * It is only a kernel address space fault iff:
 		 *	1. (type & T_USER) == 0  and
@@ -613,7 +621,6 @@
 			goto we_re_toast;
 		}
 #endif
-
 		/* Fault the original page in. */
 		onfault = pcb->pcb_onfault;
 		pcb->pcb_onfault = NULL;
@@ -782,32 +789,28 @@
 	userret(l);
 }
 
-/*
- * XXX This is a terrible name.
+/* 
+ * startlwp: start of a new LWP.
  */
 void
-upcallret(struct lwp *l)
+startlwp(void *arg)
 {
-	KERNEL_UNLOCK_LAST(l);
+	ucontext_t *uc = arg;
+	lwp_t *l = curlwp;
+	int error;
+
+	error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
+	KASSERT(error == 0);
+	pool_put(&lwp_uc_pool, uc);
 	userret(l);
 }
 
-/* 
- * Start a new LWP
+/*
+ * XXX_SA: This is a terrible name.
  */
 void
-startlwp(void *arg)
+upcallret(struct lwp *l)
 {
-	int err;
-	ucontext_t *uc = arg;
-	struct lwp *l = curlwp;
-
-	err = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
-#if DIAGNOSTIC
-	if (err) {
-		printf("Error %d from cpu_setmcontext.", err);
-	}
-#endif
-	pool_put(&lwp_uc_pool, uc);
+	KERNEL_UNLOCK_LAST(l);
 	userret(l);
 }

Reply via email to