| @@ -1,15 +1,15 @@ | | | @@ -1,15 +1,15 @@ |
1 | | | 1 | |
2 | /* $NetBSD: trap.c,v 1.284 2017/02/23 03:34:22 kamil Exp $ */ | | 2 | /* $NetBSD: trap.c,v 1.285 2017/03/09 00:16:51 chs Exp $ */ |
3 | | | 3 | |
4 | /*- | | 4 | /*- |
5 | * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. | | 5 | * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * This code is derived from software contributed to The NetBSD Foundation | | 8 | * This code is derived from software contributed to The NetBSD Foundation |
9 | * by Charles M. Hannum. | | 9 | * by Charles M. Hannum. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. | | 15 | * notice, this list of conditions and the following disclaimer. |
| @@ -59,27 +59,27 @@ | | | @@ -59,27 +59,27 @@ |
59 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 59 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
60 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 60 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
61 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 61 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
62 | * SUCH DAMAGE. | | 62 | * SUCH DAMAGE. |
63 | * | | 63 | * |
64 | * @(#)trap.c 7.4 (Berkeley) 5/13/91 | | 64 | * @(#)trap.c 7.4 (Berkeley) 5/13/91 |
65 | */ | | 65 | */ |
66 | | | 66 | |
67 | /* | | 67 | /* |
68 | * 386 Trap and System call handling | | 68 | * 386 Trap and System call handling |
69 | */ | | 69 | */ |
70 | | | 70 | |
71 | #include <sys/cdefs.h> | | 71 | #include <sys/cdefs.h> |
72 | __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.284 2017/02/23 03:34:22 kamil Exp $"); | | 72 | __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.285 2017/03/09 00:16:51 chs Exp $"); |
73 | | | 73 | |
74 | #include "opt_ddb.h" | | 74 | #include "opt_ddb.h" |
75 | #include "opt_kgdb.h" | | 75 | #include "opt_kgdb.h" |
76 | #include "opt_lockdebug.h" | | 76 | #include "opt_lockdebug.h" |
77 | #include "opt_multiprocessor.h" | | 77 | #include "opt_multiprocessor.h" |
78 | #include "opt_vm86.h" | | 78 | #include "opt_vm86.h" |
79 | #include "opt_xen.h" | | 79 | #include "opt_xen.h" |
80 | #include "opt_dtrace.h" | | 80 | #include "opt_dtrace.h" |
81 | | | 81 | |
82 | #include <sys/param.h> | | 82 | #include <sys/param.h> |
83 | #include <sys/systm.h> | | 83 | #include <sys/systm.h> |
84 | #include <sys/proc.h> | | 84 | #include <sys/proc.h> |
85 | #include <sys/acct.h> | | 85 | #include <sys/acct.h> |
| @@ -115,27 +115,26 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.2 | | | @@ -115,27 +115,26 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.2 |
115 | #ifdef KDTRACE_HOOKS | | 115 | #ifdef KDTRACE_HOOKS |
116 | #include <sys/dtrace_bsd.h> | | 116 | #include <sys/dtrace_bsd.h> |
117 | | | 117 | |
118 | /* | | 118 | /* |
119 | * This is a hook which is initialized by the dtrace module | | 119 | * This is a hook which is initialized by the dtrace module |
120 | * to handle traps which might occur during DTrace probe | | 120 | * to handle traps which might occur during DTrace probe |
121 | * execution. | | 121 | * execution. |
122 | */ | | 122 | */ |
123 | dtrace_trap_func_t dtrace_trap_func = NULL; | | 123 | dtrace_trap_func_t dtrace_trap_func = NULL; |
124 | | | 124 | |
125 | dtrace_doubletrap_func_t dtrace_doubletrap_func = NULL; | | 125 | dtrace_doubletrap_func_t dtrace_doubletrap_func = NULL; |
126 | #endif | | 126 | #endif |
127 | | | 127 | |
128 | | | | |
129 | void trap(struct trapframe *); | | 128 | void trap(struct trapframe *); |
130 | void trap_tss(struct i386tss *, int, int); | | 129 | void trap_tss(struct i386tss *, int, int); |
131 | void trap_return_fault_return(struct trapframe *) __dead; | | 130 | void trap_return_fault_return(struct trapframe *) __dead; |
132 | | | 131 | |
133 | const char * const trap_type[] = { | | 132 | const char * const trap_type[] = { |
134 | "privileged instruction fault", /* 0 T_PRIVINFLT */ | | 133 | "privileged instruction fault", /* 0 T_PRIVINFLT */ |
135 | "breakpoint trap", /* 1 T_BPTFLT */ | | 134 | "breakpoint trap", /* 1 T_BPTFLT */ |
136 | "arithmetic trap", /* 2 T_ARITHTRAP */ | | 135 | "arithmetic trap", /* 2 T_ARITHTRAP */ |
137 | "asynchronous system trap", /* 3 T_ASTFLT */ | | 136 | "asynchronous system trap", /* 3 T_ASTFLT */ |
138 | "protection fault", /* 4 T_PROTFLT */ | | 137 | "protection fault", /* 4 T_PROTFLT */ |
139 | "trace trap", /* 5 T_TRCTRAP */ | | 138 | "trace trap", /* 5 T_TRCTRAP */ |
140 | "page fault", /* 6 T_PAGEFLT */ | | 139 | "page fault", /* 6 T_PAGEFLT */ |
141 | "alignment fault", /* 7 T_ALIGNFLT */ | | 140 | "alignment fault", /* 7 T_ALIGNFLT */ |
| @@ -151,26 +150,30 @@ const char * const trap_type[] = { | | | @@ -151,26 +150,30 @@ const char * const trap_type[] = { |
151 | "stack fault", /* 17 T_STKFLT */ | | 150 | "stack fault", /* 17 T_STKFLT */ |
152 | "machine check fault", /* 18 T_MCA */ | | 151 | "machine check fault", /* 18 T_MCA */ |
153 | "SSE FP exception", /* 19 T_XMM */ | | 152 | "SSE FP exception", /* 19 T_XMM */ |
154 | "reserved trap", /* 20 T_RESERVED */ | | 153 | "reserved trap", /* 20 T_RESERVED */ |
155 | }; | | 154 | }; |
156 | int trap_types = __arraycount(trap_type); | | 155 | int trap_types = __arraycount(trap_type); |
157 | | | 156 | |
158 | #ifdef DEBUG | | 157 | #ifdef DEBUG |
159 | int trapdebug = 0; | | 158 | int trapdebug = 0; |
160 | #endif | | 159 | #endif |
161 | | | 160 | |
162 | #define IDTVEC(name) __CONCAT(X, name) | | 161 | #define IDTVEC(name) __CONCAT(X, name) |
163 | | | 162 | |
| | | 163 | #ifdef TRAP_SIGDEBUG |
| | | 164 | static void frame_dump(struct trapframe *, struct pcb *); |
| | | 165 | #endif |
| | | 166 | |
164 | void | | 167 | void |
165 | trap_tss(struct i386tss *tss, int trapno, int code) | | 168 | trap_tss(struct i386tss *tss, int trapno, int code) |
166 | { | | 169 | { |
167 | struct trapframe tf; | | 170 | struct trapframe tf; |
168 | | | 171 | |
169 | tf.tf_gs = tss->tss_gs; | | 172 | tf.tf_gs = tss->tss_gs; |
170 | tf.tf_fs = tss->tss_fs; | | 173 | tf.tf_fs = tss->tss_fs; |
171 | tf.tf_es = tss->__tss_es; | | 174 | tf.tf_es = tss->__tss_es; |
172 | tf.tf_ds = tss->__tss_ds; | | 175 | tf.tf_ds = tss->__tss_ds; |
173 | tf.tf_edi = tss->__tss_edi; | | 176 | tf.tf_edi = tss->__tss_edi; |
174 | tf.tf_esi = tss->__tss_esi; | | 177 | tf.tf_esi = tss->__tss_esi; |
175 | tf.tf_ebp = tss->tss_ebp; | | 178 | tf.tf_ebp = tss->tss_ebp; |
176 | tf.tf_ebx = tss->__tss_ebx; | | 179 | tf.tf_ebx = tss->__tss_ebx; |
| @@ -214,28 +217,28 @@ onfault_handler(const struct pcb *pcb, c | | | @@ -214,28 +217,28 @@ onfault_handler(const struct pcb *pcb, c |
214 | | | 217 | |
215 | static void | | 218 | static void |
216 | trap_print(const struct trapframe *frame, const lwp_t *l) | | 219 | trap_print(const struct trapframe *frame, const lwp_t *l) |
217 | { | | 220 | { |
218 | const int type = frame->tf_trapno; | | 221 | const int type = frame->tf_trapno; |
219 | | | 222 | |
220 | if (frame->tf_trapno < trap_types) { | | 223 | if (frame->tf_trapno < trap_types) { |
221 | printf("fatal %s", trap_type[type]); | | 224 | printf("fatal %s", trap_type[type]); |
222 | } else { | | 225 | } else { |
223 | printf("unknown trap %d", type); | | 226 | printf("unknown trap %d", type); |
224 | } | | 227 | } |
225 | printf(" in %s mode\n", (type & T_USER) ? "user" : "supervisor"); | | 228 | printf(" in %s mode\n", (type & T_USER) ? "user" : "supervisor"); |
226 | | | 229 | |
227 | printf("trap type %d code %x eip %x cs %x eflags %x cr2 %lx " | | 230 | printf("trap type %d code %#x eip %#x cs %#x eflags %#x cr2 %#lx " |
228 | "ilevel %x esp %x\n", | | 231 | "ilevel %#x esp %#x\n", |
229 | type, frame->tf_err, frame->tf_eip, frame->tf_cs, frame->tf_eflags, | | 232 | type, frame->tf_err, frame->tf_eip, frame->tf_cs, frame->tf_eflags, |
230 | (long)rcr2(), curcpu()->ci_ilevel, frame->tf_esp); | | 233 | (long)rcr2(), curcpu()->ci_ilevel, frame->tf_esp); |
231 | | | 234 | |
232 | printf("curlwp %p pid %d lid %d lowest kstack %p\n", | | 235 | printf("curlwp %p pid %d lid %d lowest kstack %p\n", |
233 | l, l->l_proc->p_pid, l->l_lid, KSTACK_LOWEST_ADDR(l)); | | 236 | l, l->l_proc->p_pid, l->l_lid, KSTACK_LOWEST_ADDR(l)); |
234 | } | | 237 | } |
235 | | | 238 | |
236 | /* | | 239 | /* |
237 | * trap(frame): exception, fault, and trap interface to BSD kernel. | | 240 | * trap(frame): exception, fault, and trap interface to BSD kernel. |
238 | * | | 241 | * |
239 | * This common code is called from assembly language IDT gate entry routines | | 242 | * This common code is called from assembly language IDT gate entry routines |
240 | * that prepare a suitable stack frame, and restore this frame after the | | 243 | * that prepare a suitable stack frame, and restore this frame after the |
241 | * exception has been processed. Note that the effect is as if the arguments | | 244 | * exception has been processed. Note that the effect is as if the arguments |
| @@ -663,27 +666,27 @@ faultcommon: | | | @@ -663,27 +666,27 @@ faultcommon: |
663 | case ENOMEM: | | 666 | case ENOMEM: |
664 | ksi.ksi_signo = SIGKILL; | | 667 | ksi.ksi_signo = SIGKILL; |
665 | printf("UVM: pid %d.%d (%s), uid %d killed: " | | 668 | printf("UVM: pid %d.%d (%s), uid %d killed: " |
666 | "out of swap\n", p->p_pid, l->l_lid, p->p_comm, | | 669 | "out of swap\n", p->p_pid, l->l_lid, p->p_comm, |
667 | l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); | | 670 | l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); |
668 | break; | | 671 | break; |
669 | default: | | 672 | default: |
670 | ksi.ksi_signo = SIGSEGV; | | 673 | ksi.ksi_signo = SIGSEGV; |
671 | ksi.ksi_code = SEGV_MAPERR; | | 674 | ksi.ksi_code = SEGV_MAPERR; |
672 | break; | | 675 | break; |
673 | } | | 676 | } |
674 | | | 677 | |
675 | #ifdef TRAP_SIGDEBUG | | 678 | #ifdef TRAP_SIGDEBUG |
676 | printf("pid %d.%d (%s): signal %d at eip %x addr %lx " | | 679 | printf("pid %d.%d (%s): signal %d at eip %#x addr %#lx " |
677 | "error %d\n", p->p_pid, l->l_lid, p->p_comm, ksi.ksi_signo, | | 680 | "error %d\n", p->p_pid, l->l_lid, p->p_comm, ksi.ksi_signo, |
678 | frame->tf_eip, va, error); | | 681 | frame->tf_eip, va, error); |
679 | #endif | | 682 | #endif |
680 | (*p->p_emul->e_trapsignal)(l, &ksi); | | 683 | (*p->p_emul->e_trapsignal)(l, &ksi); |
681 | break; | | 684 | break; |
682 | } | | 685 | } |
683 | | | 686 | |
684 | case T_TRCTRAP: | | 687 | case T_TRCTRAP: |
685 | /* | | 688 | /* |
686 | * Ignore debug register trace traps due to | | 689 | * Ignore debug register trace traps due to |
687 | * accesses in the user's address space, which | | 690 | * accesses in the user's address space, which |
688 | * can happen under several conditions such as | | 691 | * can happen under several conditions such as |
689 | * if a user sets a watchpoint on a buffer and | | 692 | * if a user sets a watchpoint on a buffer and |
| @@ -758,13 +761,47 @@ trapsignal: | | | @@ -758,13 +761,47 @@ trapsignal: |
758 | void | | 761 | void |
759 | startlwp(void *arg) | | 762 | startlwp(void *arg) |
760 | { | | 763 | { |
761 | ucontext_t *uc = arg; | | 764 | ucontext_t *uc = arg; |
762 | lwp_t *l = curlwp; | | 765 | lwp_t *l = curlwp; |
763 | int error __diagused; | | 766 | int error __diagused; |
764 | | | 767 | |
765 | error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags); | | 768 | error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags); |
766 | KASSERT(error == 0); | | 769 | KASSERT(error == 0); |
767 | | | 770 | |
768 | kmem_free(uc, sizeof(ucontext_t)); | | 771 | kmem_free(uc, sizeof(ucontext_t)); |
769 | userret(l); | | 772 | userret(l); |
770 | } | | 773 | } |
| | | 774 | |
| | | 775 | #ifdef TRAP_SIGDEBUG |
| | | 776 | void |
| | | 777 | frame_dump(struct trapframe *tf, struct pcb *pcb) |
| | | 778 | { |
| | | 779 | int i; |
| | | 780 | unsigned long *p; |
| | | 781 | uint64_t fsd, gsd; |
| | | 782 | |
| | | 783 | printf("trapframe %p\n", tf); |
| | | 784 | printf("eip 0x%08x esp 0x%08x efl 0x%08x\n", |
| | | 785 | tf->tf_eip, tf->tf_esp, tf->tf_eflags); |
| | | 786 | printf("edi 0x%08x esi 0x%08x edx 0x%08x\n", |
| | | 787 | tf->tf_edi, tf->tf_esi, tf->tf_edx); |
| | | 788 | printf("ecx 0x%08x\n", |
| | | 789 | tf->tf_ecx); |
| | | 790 | printf("ebp 0x%08x ebx 0x%08x eax 0x%08x\n", |
| | | 791 | tf->tf_ebp, tf->tf_ebx, tf->tf_eax); |
| | | 792 | printf("cs 0x%04x ds 0x%04x es 0x%04x " |
| | | 793 | "fs 0x%04x gs 0x%04x ss 0x%04x\n", |
| | | 794 | tf->tf_cs & 0xffff, tf->tf_ds & 0xffff, tf->tf_es & 0xffff, |
| | | 795 | tf->tf_fs & 0xffff, tf->tf_gs & 0xffff, tf->tf_ss & 0xffff); |
| | | 796 | memcpy(&fsd, &pcb->pcb_fsd, sizeof(fsd)); |
| | | 797 | memcpy(&gsd, &pcb->pcb_gsd, sizeof(gsd)); |
| | | 798 | printf("fsbase 0x%016llx gsbase 0x%016llx\n", fsd, gsd); |
| | | 799 | printf("\n"); |
| | | 800 | printf("Stack dump:\n"); |
| | | 801 | for (i = 0, p = (unsigned long *) tf; i < 20; i ++, p += 8) |
| | | 802 | printf(" 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx" |
| | | 803 | " 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n", |
| | | 804 | p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); |
| | | 805 | printf("\n"); |
| | | 806 | } |
| | | 807 | #endif |