Module Name:    src
Committed By:   maxv
Date:           Sun Sep  3 08:52:18 UTC 2017

Modified Files:
        src/sys/arch/amd64/amd64: amd64_trap.S trap.c
        src/sys/arch/amd64/conf: ALL

Log Message:
Remove useless debug code, and split trap() into smaller functions, easier
to understand. NMIs take another, faster path now. No functional change
beyond that.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/amd64/amd64/amd64_trap.S
cvs rdiff -u -r1.96 -r1.97 src/sys/arch/amd64/amd64/trap.c
cvs rdiff -u -r1.68 -r1.69 src/sys/arch/amd64/conf/ALL

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/amd64_trap.S
diff -u src/sys/arch/amd64/amd64/amd64_trap.S:1.9 src/sys/arch/amd64/amd64/amd64_trap.S:1.10
--- src/sys/arch/amd64/amd64/amd64_trap.S:1.9	Thu Aug 31 10:30:58 2017
+++ src/sys/arch/amd64/amd64/amd64_trap.S	Sun Sep  3 08:52:18 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: amd64_trap.S,v 1.9 2017/08/31 10:30:58 maxv Exp $	*/
+/*	$NetBSD: amd64_trap.S,v 1.10 2017/09/03 08:52:18 maxv Exp $	*/
 
 /*
  * Copyright (c) 1998, 2007, 2008, 2017 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
 
 #if 0
 #include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.9 2017/08/31 10:30:58 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amd64_trap.S,v 1.10 2017/09/03 08:52:18 maxv Exp $");
 #endif
 
 /*
@@ -135,7 +135,7 @@ IDTVEC(trap02)
 	swapgs
 	movq	%rsp,%rdi
 	incq	CPUVAR(NTRAP)
-	call	_C_LABEL(trap)
+	call	_C_LABEL(nmitrap)
 	swapgs
 	jmp	nmileave
 

Index: src/sys/arch/amd64/amd64/trap.c
diff -u src/sys/arch/amd64/amd64/trap.c:1.96 src/sys/arch/amd64/amd64/trap.c:1.97
--- src/sys/arch/amd64/amd64/trap.c:1.96	Mon Apr 24 17:03:43 2017
+++ src/sys/arch/amd64/amd64/trap.c	Sun Sep  3 08:52:18 2017
@@ -1,11 +1,11 @@
-/*	$NetBSD: trap.c,v 1.96 2017/04/24 17:03:43 chs Exp $	*/
+/*	$NetBSD: trap.c,v 1.97 2017/09/03 08:52:18 maxv Exp $	*/
 
-/*-
- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
+/*
+ * Copyright (c) 1998, 2000, 2017 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Charles M. Hannum.
+ * by Charles M. Hannum, and by Maxime Villard.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-/*-
+/*
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
@@ -63,12 +63,8 @@
  *	@(#)trap.c	7.4 (Berkeley) 5/13/91
  */
 
-/*
- * 386 Trap and System call handling
- */
-
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.96 2017/04/24 17:03:43 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.97 2017/09/03 08:52:18 maxv Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -126,6 +122,7 @@ dtrace_trap_func_t	dtrace_trap_func = NU
 dtrace_doubletrap_func_t	dtrace_doubletrap_func = NULL;
 #endif
 
+void nmitrap(struct trapframe *);
 void trap(struct trapframe *);
 void trap_return_fault_return(struct trapframe *) __dead;
 
@@ -154,16 +151,8 @@ const char * const trap_type[] = {
 };
 int	trap_types = __arraycount(trap_type);
 
-#ifdef DEBUG
-int	trapdebug = 0;
-#endif
-
 #define	IDTVEC(name)	__CONCAT(X, name)
 
-#ifdef TRAP_SIGDEBUG
-static void frame_dump(struct trapframe *, struct pcb *);
-#endif
-
 static void *
 onfault_handler(const struct pcb *pcb, const struct trapframe *tf)
 {
@@ -210,6 +199,115 @@ trap_print(const struct trapframe *frame
 	    l, l->l_proc->p_pid, l->l_lid, KSTACK_LOWEST_ADDR(l));
 }
 
+void
+nmitrap(struct trapframe *frame)
+{
+	const int type = T_NMI;
+
+	if (nmi_dispatch(frame))
+		return;
+	/* NMI can be hooked up to a pushbutton for debugging */
+	if (kgdb_trap(type, frame))
+		return;
+	if (kdb_trap(type, 0, frame))
+		return;
+	/* machine/parity/power fail/"kitchen sink" faults */
+
+	x86_nmi();
+}
+
+/*
+ * Did we receive in kernel mode a trap that ought to be considered as a user
+ * trap? If this function returns, the answer is no.
+ *
+ * Such traps can be triggered when the kernel fails to return to userland,
+ * because of incorrect segment registers.
+ */
+#ifndef Xen
+static void trap_user_kernelmode(struct trapframe *, int, lwp_t *, proc_t *);
+
+static void
+trap_user_kernelmode(struct trapframe *frame, int type, lwp_t *l, proc_t *p)
+{
+	struct trapframe *vframe;
+	ksiginfo_t ksi;
+
+	if (frame->tf_rip == 0) {
+		/*
+		 * Assume that if we jumped to null we probably did it via a
+		 * null function pointer, so print the return address.
+		 */
+		printf("kernel jumped to null; return addr was %p\n",
+		    *(void **)frame->tf_rsp);
+		return;
+	}
+
+	KSI_INIT_TRAP(&ksi);
+	ksi.ksi_signo = SIGSEGV;
+	ksi.ksi_code = SEGV_ACCERR;
+	ksi.ksi_trap = type;
+
+	/*
+	 * Get %rsp value before fault - there may be a pad word below the
+	 * trap frame.
+	 */
+	vframe = (void *)frame->tf_rsp;
+
+	switch (*(uint16_t *)frame->tf_rip) {
+	case 0xcf48:	/* iretq */
+		/*
+		 * The 'iretq' instruction faulted, so we have the
+		 * 'user' registers saved after the kernel
+		 * %rip:%cs:%fl:%rsp:%ss of the iret, and below that
+		 * the user %rip:%cs:%fl:%rsp:%ss the 'iret' was
+		 * processing.
+		 * We must copy the user register back over the
+		 * kernel fault frame to generate a normal stack
+		 * frame (eg for sending a SIGSEGV).
+		 */
+		vframe = (void *)((char *)vframe
+		    - offsetof(struct trapframe, tf_rip));
+		memmove(vframe, frame, offsetof(struct trapframe, tf_rip));
+		/* Set the faulting address to the user %rip */
+		ksi.ksi_addr = (void *)vframe->tf_rip;
+		break;
+
+	case 0x848e:	/* mov 0xa8(%rsp),%es (8e 84 24 a8 00 00 00) */
+	case 0x9c8e:	/* mov 0xb0(%rsp),%ds (8e 9c 24 b0 00 00 00) */
+#ifdef USER_LDT
+	case 0xa48e:	/* mov 0xa0(%rsp),%fs (8e a4 24 a0 00 00 00) */
+	case 0xac8e:	/* mov 0x98(%rsp),%gs (8e ac 24 98 00 00 00) */
+#endif
+		/*
+		 * We faulted loading one of the user segment registers.
+		 * The stack frame containing the user registers is
+		 * still valid and pointed to by tf_rsp.
+		 */
+		if (KERNELMODE(vframe->tf_cs, vframe->tf_eflags))
+			return;
+		/* There is no valid address for the fault */
+		break;
+
+	default:
+		return;
+	}
+
+	/* XXX: worry about on-stack trampolines for nested handlers?? */
+	/* Save outer frame for any signal return */
+	l->l_md.md_regs = vframe;
+	(*p->p_emul->e_trapsignal)(l, &ksi);
+	/* Return to user by reloading the user frame */
+	trap_return_fault_return(vframe);
+	/* NOTREACHED */
+}
+#else
+/*
+ * XXX: there has to be an equivalent 'problem' but I (dsl) don't know exactly
+ * what happens! For now panic the kernel.
+ */
+#define trap_user_kernelmode(frame, type, l, p)	/* NOTHING */
+#endif
+
 /*
  * trap(frame): exception, fault, and trap interface to BSD kernel.
  *
@@ -231,9 +329,6 @@ trap(struct trapframe *frame)
 	extern char fusuintrfailure[], kcopy_fault[];
 	extern char IDTVEC(osyscall)[];
 	extern char IDTVEC(syscall32)[];
-#ifndef XEN
-	struct trapframe *vframe;
-#endif
 	ksiginfo_t ksi;
 	void *onfault;
 	int type, error;
@@ -252,12 +347,7 @@ trap(struct trapframe *frame)
 	}
 	type = frame->tf_trapno;
 
-#ifdef DEBUG
-	if (trapdebug) {
-		trap_print(frame, l);
-	}
-#endif
-	if (type != T_NMI && !KERNELMODE(frame->tf_cs, frame->tf_rflags)) {
+	if (!KERNELMODE(frame->tf_cs, frame->tf_rflags)) {
 		type |= T_USER;
 		l->l_md.md_regs = frame;
 		LWP_CACHE_CREDS(l, p);
@@ -322,92 +412,9 @@ copyfault:
 			return;
 		}
 
-		/*
-		 * Check for failure during return to user mode.
-		 * This can happen loading invalid values into the segment
-		 * registers, or during the 'iret' itself.
-		 *
-		 * We do this by looking at the instruction we faulted on.
-		 * The specific instructions we recognize only happen when
-		 * returning from a trap, syscall, or interrupt.
-		 */
-
 kernelfault:
-#ifdef XEN
-		/*
-		 * XXX: there has to be an equivalent 'problem'
-		 * but I (dsl) don't know exactly what happens!
-		 * For now panic the kernel.
-		 */
+		trap_user_kernelmode(frame, type, l, p);
 		goto we_re_toast;
-#else
-		KSI_INIT_TRAP(&ksi);
-		ksi.ksi_signo = SIGSEGV;
-		ksi.ksi_code = SEGV_ACCERR;
-		ksi.ksi_trap = type;
-
-		/* Get %rsp value before fault - there may be a pad word
-		 * below the trap frame. */
-		vframe = (void *)frame->tf_rsp;
-		if (frame->tf_rip == 0) {
-			/*
-			 * Assume that if we jumped to null we
-			 * probably did it via a null function
-			 * pointer, so print the return address.
-			 */
-			printf("kernel jumped to null; return addr was %p\n",
-			       *(void **)frame->tf_rsp);
-			goto we_re_toast;
-		}
-		switch (*(uint16_t *)frame->tf_rip) {
-		case 0xcf48:	/* iretq */
-			/*
-			 * The 'iretq' instruction faulted, so we have the
-			 * 'user' registers saved after the kernel
-			 * %rip:%cs:%fl:%rsp:%ss of the iret, and below that
-			 * the user %rip:%cs:%fl:%rsp:%ss the 'iret' was
-			 * processing.
-			 * We must copy the user register back over the
-			 * kernel fault frame to generate a normal stack
-			 * frame (eg for sending a SIGSEGV).
-			 */
-			vframe = (void *)((char *)vframe
-			    - offsetof(struct trapframe, tf_rip));
-			memmove(vframe, frame,
-			    offsetof(struct trapframe, tf_rip));
-			/* Set the faulting address to the user %eip */
-			ksi.ksi_addr = (void *)vframe->tf_rip;
-			break;
-		case 0x848e:	/* mov 0xa8(%rsp),%es (8e 84 24 a8 00 00 00) */
-		case 0x9c8e:	/* mov 0xb0(%rsp),%ds (8e 9c 24 b0 00 00 00) */
-#ifdef USER_LDT
-		case 0xa48e:	/* mov 0xa0(%rsp),%fs (8e a4 24 a0 00 00 00) */
-		case 0xac8e:	/* mov 0x98(%rsp),%gs (8e ac 24 98 00 00 00) */
-#endif
-			/*
-			 * We faulted loading one of the user segment registers.
-			 * The stack frame containing the user registers is
-			 * still valid and pointed to by tf_rsp.
-			 * Maybe we should check the iretq follows.
-			 */
-			if (KERNELMODE(vframe->tf_cs, vframe->tf_eflags))
-				goto we_re_toast;
-			/* There is no valid address for the fault */
-			break;
-
-		default:
-			goto we_re_toast;
-		}
-
-		/* XXX: worry about on-stack trampolines for nested
-		 * handlers?? */
-		/* Save outer frame for any signal return */
-		l->l_md.md_regs = vframe;
-		(*p->p_emul->e_trapsignal)(l, &ksi);
-		/* Return to user by reloading the user frame */
-		trap_return_fault_return(vframe);
-		/* NOTREACHED */
-#endif
 
 	case T_PROTFLT|T_USER:		/* protection fault */
 #if defined(COMPAT_NETBSD32) && defined(COMPAT_10)
@@ -435,11 +442,6 @@ kernelfault:
 	case T_SEGNPFLT|T_USER:
 	case T_STKFLT|T_USER:
 	case T_ALIGNFLT|T_USER:
-#ifdef TRAP_SIGDEBUG
-		printf("pid %d.%d (%s): BUS/SEGV (%#x) at rip %#lx addr %#lx\n",
-		    p->p_pid, l->l_lid, p->p_comm, type, frame->tf_rip, rcr2());
-		frame_dump(frame, pcb);
-#endif
 		KSI_INIT_TRAP(&ksi);
 		ksi.ksi_trap = type & ~T_USER;
 		ksi.ksi_addr = (void *)rcr2();
@@ -467,13 +469,8 @@ kernelfault:
 		}
 		goto trapsignal;
 
-	case T_PRIVINFLT|T_USER:	/* privileged instruction fault */
-	case T_FPOPFLT|T_USER:		/* coprocessor operand fault */
-#ifdef TRAP_SIGDEBUG
-		printf("pid %d.%d (%s): ILL at rip %#lx addr %#lx\n",
-		    p->p_pid, l->l_lid, p->p_comm, frame->tf_rip, rcr2());
-		frame_dump(frame, pcb);
-#endif
+	case T_PRIVINFLT|T_USER:
+	case T_FPOPFLT|T_USER:
 		KSI_INIT_TRAP(&ksi);
 		ksi.ksi_signo = SIGILL;
 		ksi.ksi_trap = type & ~T_USER;
@@ -557,7 +554,7 @@ kernelfault:
 
 		goto faultcommon;
 
-	case T_PAGEFLT|T_USER: {	/* page fault */
+	case T_PAGEFLT|T_USER: {
 		register vaddr_t va;
 		register struct vmspace *vm;
 		register struct vm_map *map;
@@ -693,13 +690,6 @@ faultcommon:
 			break;
 		}
 
-#ifdef TRAP_SIGDEBUG
-		printf("pid %d.%d (%s): signal %d at rip %#lx addr %#lx "
-		    "error %d trap %d cr2 %p\n", p->p_pid, l->l_lid, p->p_comm,
-		    ksi.ksi_signo, frame->tf_rip, va, error, ksi.ksi_trap,
-		    ksi.ksi_addr);
-		frame_dump(frame, pcb);
-#endif
 		(*p->p_emul->e_trapsignal)(l, &ksi);
 		break;
 	}
@@ -726,12 +716,11 @@ faultcommon:
 		}
 		goto we_re_toast;
 
-	case T_BPTFLT|T_USER:		/* bpt instruction fault */
-	case T_TRCTRAP|T_USER:		/* trace trap */
+	case T_BPTFLT|T_USER:
+	case T_TRCTRAP|T_USER:
 		/*
 		 * 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);
@@ -747,19 +736,6 @@ faultcommon:
 			(*p->p_emul->e_trapsignal)(l, &ksi);
 		}
 		break;
-
-	case T_NMI:
-		if (nmi_dispatch(frame))
-			return;
-		/* NMI can be hooked up to a pushbutton for debugging */
-		if (kgdb_trap(type, frame))
-			return;
-		if (kdb_trap(type, 0, frame))
-			return;
-		/* machine/parity/power fail/"kitchen sink" faults */
-
-		x86_nmi();
-		return;
 	}
 
 	if ((type & T_USER) == 0)
@@ -772,7 +748,7 @@ trapsignal:
 	userret(l);
 }
 
-/* 
+/*
  * startlwp: start of a new LWP.
  */
 void
@@ -789,37 +765,3 @@ startlwp(void *arg)
 	userret(l);
 }
 
-#ifdef TRAP_SIGDEBUG
-void
-frame_dump(struct trapframe *tf, struct pcb *pcb)
-{
-	int i;
-	unsigned long *p;
-
-	printf("trapframe %p\n", tf);
-	printf("rip 0x%016lx  rsp 0x%016lx  rfl 0x%016lx\n",
-	    tf->tf_rip, tf->tf_rsp, tf->tf_rflags);
-	printf("rdi 0x%016lx  rsi 0x%016lx  rdx 0x%016lx\n",
-	    tf->tf_rdi, tf->tf_rsi, tf->tf_rdx);
-	printf("rcx 0x%016lx  r8  0x%016lx  r9  0x%016lx\n",
-	    tf->tf_rcx, tf->tf_r8, tf->tf_r9);
-	printf("r10 0x%016lx  r11 0x%016lx  r12 0x%016lx\n",
-	    tf->tf_r10, tf->tf_r11, tf->tf_r12);
-	printf("r13 0x%016lx  r14 0x%016lx  r15 0x%016lx\n",
-	    tf->tf_r13, tf->tf_r14, tf->tf_r15);
-	printf("rbp 0x%016lx  rbx 0x%016lx  rax 0x%016lx\n",
-	    tf->tf_rbp, tf->tf_rbx, tf->tf_rax);
-	printf("cs 0x%04lx  ds 0x%04lx  es 0x%04lx  "
-	       "fs 0x%04lx  gs 0x%04lx  ss 0x%04lx\n",
-		tf->tf_cs & 0xffff, tf->tf_ds & 0xffff, tf->tf_es & 0xffff,
-		tf->tf_fs & 0xffff, tf->tf_gs & 0xffff, tf->tf_ss & 0xffff);
-	printf("fsbase 0x%016lx gsbase 0x%016lx\n",
-	       pcb->pcb_fs, pcb->pcb_gs);
-	printf("\n");
-	printf("Stack dump:\n");
-	for (i = 0, p = (unsigned long *) tf; i < 20; i ++, p += 4)
-		printf(" 0x%.16lx  0x%.16lx  0x%.16lx  0x%.16lx\n",
-		       p[0], p[1], p[2], p[3]);
-	printf("\n");
-}
-#endif

Index: src/sys/arch/amd64/conf/ALL
diff -u src/sys/arch/amd64/conf/ALL:1.68 src/sys/arch/amd64/conf/ALL:1.69
--- src/sys/arch/amd64/conf/ALL:1.68	Wed Aug 30 15:44:01 2017
+++ src/sys/arch/amd64/conf/ALL	Sun Sep  3 08:52:18 2017
@@ -1,4 +1,4 @@
-# $NetBSD: ALL,v 1.68 2017/08/30 15:44:01 maxv Exp $
+# $NetBSD: ALL,v 1.69 2017/09/03 08:52:18 maxv Exp $
 # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
 #
 # ALL machine description file
@@ -17,7 +17,7 @@ include 	"arch/amd64/conf/std.amd64"
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident		"ALL-$Revision: 1.68 $"
+#ident		"ALL-$Revision: 1.69 $"
 
 maxusers	64		# estimated number of users
 
@@ -2273,7 +2273,6 @@ options TLP_DEBUG
 options TP_DEBUG
 options TRACE_DEBUG
 options TRAPDEBUG
-options TRAP_SIGDEBUG
 options TRISADEBUG
 options TRM_DEBUG
 options TROPICDEBUG

Reply via email to