Tue Mar 3 13:23:49 2015 UTC ()
Handle EINVAL in the fault path and send SIGBUS on mmap'd access past EOF


(martin)
diff -r1.132 -r1.133 src/sys/arch/vax/vax/trap.c

cvs diff -r1.132 -r1.133 src/sys/arch/vax/vax/trap.c (switch to unified diff)

--- src/sys/arch/vax/vax/trap.c 2013/10/25 16:30:52 1.132
+++ src/sys/arch/vax/vax/trap.c 2015/03/03 13:23:48 1.133
@@ -1,396 +1,406 @@ @@ -1,396 +1,406 @@
1/* $NetBSD: trap.c,v 1.132 2013/10/25 16:30:52 martin Exp $ */ 1/* $NetBSD: trap.c,v 1.133 2015/03/03 13:23:48 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994 Ludd, University of Lule}, Sweden. 4 * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed at Ludd, University of Lule}. 17 * This product includes software developed at Ludd, University of Lule}.
18 * 4. The name of the author may not be used to endorse or promote products 18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission 19 * derived from this software without specific prior written permission
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33 /* All bugs are subject to removal without further notice */ 33 /* All bugs are subject to removal without further notice */
34  34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.132 2013/10/25 16:30:52 martin Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.133 2015/03/03 13:23:48 martin Exp $");
37 37
38#include "opt_ddb.h" 38#include "opt_ddb.h"
39#include "opt_multiprocessor.h" 39#include "opt_multiprocessor.h"
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/cpu.h> 43#include <sys/cpu.h>
44#include <sys/exec.h> 44#include <sys/exec.h>
45#include <sys/kauth.h> 45#include <sys/kauth.h>
46#include <sys/proc.h> 46#include <sys/proc.h>
47#include <sys/signalvar.h> 47#include <sys/signalvar.h>
48 48
49#include <uvm/uvm_extern.h> 49#include <uvm/uvm_extern.h>
50 50
51#include <machine/trap.h> 51#include <machine/trap.h>
52#include <machine/userret.h> 52#include <machine/userret.h>
53 53
54#ifdef DDB 54#ifdef DDB
55#include <machine/db_machdep.h> 55#include <machine/db_machdep.h>
56#endif 56#endif
57#include <vax/vax/db_disasm.h> 57#include <vax/vax/db_disasm.h>
58#include <kern/syscalls.c> 58#include <kern/syscalls.c>
59#include <sys/ktrace.h> 59#include <sys/ktrace.h>
60 60
61#ifdef TRAPDEBUG 61#ifdef TRAPDEBUG
62volatile int faultdebug = 0; 62volatile int faultdebug = 0;
63#endif 63#endif
64 64
65int cpu_printfataltraps = 0; 65int cpu_printfataltraps = 0;
66 66
67void trap (struct trapframe *); 67void trap (struct trapframe *);
68 68
69const char * const traptypes[]={ 69const char * const traptypes[]={
70 "reserved addressing", 70 "reserved addressing",
71 "privileged instruction", 71 "privileged instruction",
72 "reserved operand", 72 "reserved operand",
73 "breakpoint instruction", 73 "breakpoint instruction",
74 "XFC instruction", 74 "XFC instruction",
75 "system call ", 75 "system call ",
76 "arithmetic trap", 76 "arithmetic trap",
77 "asynchronous system trap", 77 "asynchronous system trap",
78 "page table length fault", 78 "page table length fault",
79 "translation violation fault", 79 "translation violation fault",
80 "trace trap", 80 "trace trap",
81 "compatibility mode fault", 81 "compatibility mode fault",
82 "access violation fault", 82 "access violation fault",
83 "", 83 "",
84 "", 84 "",
85 "KSP invalid", 85 "KSP invalid",
86 "", 86 "",
87 "kernel debugger trap" 87 "kernel debugger trap"
88}; 88};
89int no_traps = 18; 89int no_traps = 18;
90 90
91#define USERMODE_P(tf) ((((tf)->tf_psl) & (PSL_U)) == PSL_U) 91#define USERMODE_P(tf) ((((tf)->tf_psl) & (PSL_U)) == PSL_U)
92 92
93void 93void
94trap(struct trapframe *tf) 94trap(struct trapframe *tf)
95{ 95{
96 u_int sig = 0, type = tf->tf_trap, code = 0; 96 u_int sig = 0, type = tf->tf_trap, code = 0;
97 u_int rv, addr; 97 u_int rv, addr;
98 bool trapsig = true; 98 bool trapsig = true;
99 const bool usermode = USERMODE_P(tf); 99 const bool usermode = USERMODE_P(tf);
100 struct lwp * const l = curlwp; 100 struct lwp * const l = curlwp;
101 struct proc * const p = l->l_proc; 101 struct proc * const p = l->l_proc;
102 struct pcb * const pcb = lwp_getpcb(l); 102 struct pcb * const pcb = lwp_getpcb(l);
103 u_quad_t oticks = 0; 103 u_quad_t oticks = 0;
104 struct vmspace *vm; 104 struct vmspace *vm;
105 struct vm_map *map; 105 struct vm_map *map;
106 vm_prot_t ftype; 106 vm_prot_t ftype;
107 void *onfault = pcb->pcb_onfault; 107 void *onfault = pcb->pcb_onfault;
108 108
109 KASSERT(p != NULL); 109 KASSERT(p != NULL);
110 curcpu()->ci_data.cpu_ntrap++; 110 curcpu()->ci_data.cpu_ntrap++;
111 if (usermode) { 111 if (usermode) {
112 type |= T_USER; 112 type |= T_USER;
113 oticks = p->p_sticks; 113 oticks = p->p_sticks;
114 l->l_md.md_utf = tf;  114 l->l_md.md_utf = tf;
115 LWP_CACHE_CREDS(l, p); 115 LWP_CACHE_CREDS(l, p);
116 } 116 }
117 117
118 type &= ~(T_WRITE|T_PTEFETCH); 118 type &= ~(T_WRITE|T_PTEFETCH);
119 119
120 120
121#ifdef TRAPDEBUG 121#ifdef TRAPDEBUG
122if(tf->tf_trap==7) goto fram; 122if(tf->tf_trap==7) goto fram;
123if(faultdebug)printf("Trap: type %lx, code %lx, pc %lx, psl %lx\n", 123if(faultdebug)printf("Trap: type %lx, code %lx, pc %lx, psl %lx\n",
124 tf->tf_trap, tf->tf_code, tf->tf_pc, tf->tf_psl); 124 tf->tf_trap, tf->tf_code, tf->tf_pc, tf->tf_psl);
125fram: 125fram:
126#endif 126#endif
127 switch (type) { 127 switch (type) {
128 128
129 default: 129 default:
130#ifdef DDB 130#ifdef DDB
131 kdb_trap(tf); 131 kdb_trap(tf);
132#endif 132#endif
133 panic("trap: type %x, code %x, pc %x, psl %x", 133 panic("trap: type %x, code %x, pc %x, psl %x",
134 (u_int)tf->tf_trap, (u_int)tf->tf_code, 134 (u_int)tf->tf_trap, (u_int)tf->tf_code,
135 (u_int)tf->tf_pc, (u_int)tf->tf_psl); 135 (u_int)tf->tf_pc, (u_int)tf->tf_psl);
136 136
137 case T_KSPNOTVAL: 137 case T_KSPNOTVAL:
138 panic("%d.%d (%s): KSP invalid %#x@%#x pcb %p fp %#x psl %#x)", 138 panic("%d.%d (%s): KSP invalid %#x@%#x pcb %p fp %#x psl %#x)",
139 p->p_pid, l->l_lid, l->l_name ? l->l_name : "??", 139 p->p_pid, l->l_lid, l->l_name ? l->l_name : "??",
140 mfpr(PR_KSP), (u_int)tf->tf_pc, pcb, 140 mfpr(PR_KSP), (u_int)tf->tf_pc, pcb,
141 (u_int)tf->tf_fp, (u_int)tf->tf_psl); 141 (u_int)tf->tf_fp, (u_int)tf->tf_psl);
142 142
143 case T_TRANSFLT|T_USER: 143 case T_TRANSFLT|T_USER:
144 case T_TRANSFLT: 144 case T_TRANSFLT:
145 /* 145 /*
146 * BUG! BUG! BUG! BUG! BUG! 146 * BUG! BUG! BUG! BUG! BUG!
147 * Due to a hardware bug (at in least KA65x CPUs) a double 147 * Due to a hardware bug (at in least KA65x CPUs) a double
148 * page table fetch trap will cause a translation fault 148 * page table fetch trap will cause a translation fault
149 * even if access in the SPT PTE entry specifies 'no access'. 149 * even if access in the SPT PTE entry specifies 'no access'.
150 * In for example section 6.4.2 in VAX Architecture  150 * In for example section 6.4.2 in VAX Architecture
151 * Reference Manual it states that if a page both are invalid 151 * Reference Manual it states that if a page both are invalid
152 * and have no access set, a 'access violation fault' occurs. 152 * and have no access set, a 'access violation fault' occurs.
153 * Therefore, we must fall through here... 153 * Therefore, we must fall through here...
154 */ 154 */
155#ifdef nohwbug 155#ifdef nohwbug
156 panic("translation fault"); 156 panic("translation fault");
157#endif 157#endif
158 158
159 case T_PTELEN|T_USER: /* Page table length exceeded */ 159 case T_PTELEN|T_USER: /* Page table length exceeded */
160 case T_ACCFLT|T_USER: 160 case T_ACCFLT|T_USER:
161 if (tf->tf_code < 0) { /* Check for kernel space */ 161 if (tf->tf_code < 0) { /* Check for kernel space */
162 sig = SIGSEGV; 162 sig = SIGSEGV;
163 code = SEGV_ACCERR; 163 code = SEGV_ACCERR;
164 break; 164 break;
165 } 165 }
166 166
167 case T_PTELEN: 167 case T_PTELEN:
168#ifndef MULTIPROCESSOR 168#ifndef MULTIPROCESSOR
169 /* 169 /*
170 * If we referred to an address beyond the end of the system 170 * If we referred to an address beyond the end of the system
171 * page table, it may be due to a failed CAS 171 * page table, it may be due to a failed CAS
172 * restartable-atomic-sequence. If it is, restart it at the 172 * restartable-atomic-sequence. If it is, restart it at the
173 * beginning and restart. 173 * beginning and restart.
174 */ 174 */
175 { 175 {
176 extern const uint8_t cas32_ras_start[], cas32_ras_end[]; 176 extern const uint8_t cas32_ras_start[], cas32_ras_end[];
177 if (tf->tf_code == CASMAGIC 177 if (tf->tf_code == CASMAGIC
178 && tf->tf_pc >= (uintptr_t) cas32_ras_start 178 && tf->tf_pc >= (uintptr_t) cas32_ras_start
179 && tf->tf_pc < (uintptr_t) cas32_ras_end) { 179 && tf->tf_pc < (uintptr_t) cas32_ras_end) {
180 tf->tf_pc = (uintptr_t) cas32_ras_start; 180 tf->tf_pc = (uintptr_t) cas32_ras_start;
181 trapsig = false; 181 trapsig = false;
182 break; 182 break;
183 } 183 }
184 } 184 }
185 /* FALLTHROUGH */ 185 /* FALLTHROUGH */
186#endif 186#endif
187 case T_ACCFLT: 187 case T_ACCFLT:
188#ifdef TRAPDEBUG 188#ifdef TRAPDEBUG
189if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n", 189if(faultdebug)printf("trap accflt type %lx, code %lx, pc %lx, psl %lx\n",
190 tf->tf_trap, tf->tf_code, tf->tf_pc, tf->tf_psl); 190 tf->tf_trap, tf->tf_code, tf->tf_pc, tf->tf_psl);
191#endif 191#endif
192#ifdef DIAGNOSTIC 192#ifdef DIAGNOSTIC
193 if (p == 0) 193 if (p == 0)
194 panic("trap: access fault: addr %lx code %lx", 194 panic("trap: access fault: addr %lx code %lx",
195 tf->tf_pc, tf->tf_code); 195 tf->tf_pc, tf->tf_code);
196 if (tf->tf_psl & PSL_IS) 196 if (tf->tf_psl & PSL_IS)
197 panic("trap: pflt on IS"); 197 panic("trap: pflt on IS");
198#endif 198#endif
199 199
200 /* 200 /*
201 * Page tables are allocated in pmap_enter(). We get  201 * Page tables are allocated in pmap_enter(). We get
202 * info from below if it is a page table fault, but 202 * info from below if it is a page table fault, but
203 * UVM may want to map in pages without faults, so 203 * UVM may want to map in pages without faults, so
204 * because we must check for PTE pages anyway we don't 204 * because we must check for PTE pages anyway we don't
205 * bother doing it here. 205 * bother doing it here.
206 */ 206 */
207 addr = trunc_page(tf->tf_code); 207 addr = trunc_page(tf->tf_code);
208 if (!usermode && (tf->tf_code < 0)) { 208 if (!usermode && (tf->tf_code < 0)) {
209 vm = NULL; 209 vm = NULL;
210 map = kernel_map; 210 map = kernel_map;
211 211
212 } else { 212 } else {
213 vm = p->p_vmspace; 213 vm = p->p_vmspace;
214 map = &vm->vm_map; 214 map = &vm->vm_map;
215 } 215 }
216 216
217 if (tf->tf_trap & T_WRITE) 217 if (tf->tf_trap & T_WRITE)
218 ftype = VM_PROT_WRITE; 218 ftype = VM_PROT_WRITE;
219 else 219 else
220 ftype = VM_PROT_READ; 220 ftype = VM_PROT_READ;
221 221
222 pcb->pcb_onfault = NULL; 222 pcb->pcb_onfault = NULL;
223 rv = uvm_fault(map, addr, ftype); 223 rv = uvm_fault(map, addr, ftype);
224 pcb->pcb_onfault = onfault; 224 pcb->pcb_onfault = onfault;
225 if (rv != 0) { 225 if (rv != 0) {
226 if (!usermode) { 226 if (!usermode) {
227 if (onfault) { 227 if (onfault) {
228 pcb->pcb_onfault = NULL; 228 pcb->pcb_onfault = NULL;
229 tf->tf_pc = (unsigned)onfault; 229 tf->tf_pc = (unsigned)onfault;
230 tf->tf_psl &= ~PSL_FPD; 230 tf->tf_psl &= ~PSL_FPD;
231 tf->tf_r0 = rv; 231 tf->tf_r0 = rv;
232 return; 232 return;
233 } 233 }
234 printf("r0=%08lx r1=%08lx r2=%08lx r3=%08lx ", 234 printf("r0=%08lx r1=%08lx r2=%08lx r3=%08lx ",
235 tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3); 235 tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
236 printf("r4=%08lx r5=%08lx r6=%08lx r7=%08lx\n", 236 printf("r4=%08lx r5=%08lx r6=%08lx r7=%08lx\n",
237 tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7); 237 tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
238 printf( 238 printf(
239 "r8=%08lx r9=%08lx r10=%08lx r11=%08lx\n", 239 "r8=%08lx r9=%08lx r10=%08lx r11=%08lx\n",
240 tf->tf_r8, tf->tf_r9, tf->tf_r10, 240 tf->tf_r8, tf->tf_r9, tf->tf_r10,
241 tf->tf_r11); 241 tf->tf_r11);
242 printf("ap=%08lx fp=%08lx sp=%08lx pc=%08lx\n", 242 printf("ap=%08lx fp=%08lx sp=%08lx pc=%08lx\n",
243 tf->tf_ap, tf->tf_fp, tf->tf_sp, tf->tf_pc); 243 tf->tf_ap, tf->tf_fp, tf->tf_sp, tf->tf_pc);
244 panic("SEGV in kernel mode: pc %#lx addr %#lx", 244 panic("SEGV in kernel mode: pc %#lx addr %#lx",
245 tf->tf_pc, tf->tf_code); 245 tf->tf_pc, tf->tf_code);
246 } 246 }
247 code = SEGV_ACCERR; 247 switch (rv) {
248 if (rv == ENOMEM) { 248 case ENOMEM:
249 printf("UVM: pid %d (%s), uid %d killed: " 249 printf("UVM: pid %d (%s), uid %d killed: "
250 "out of swap\n", 250 "out of swap\n",
251 p->p_pid, p->p_comm, 251 p->p_pid, p->p_comm,
252 l->l_cred ? 252 l->l_cred ?
253 kauth_cred_geteuid(l->l_cred) : -1); 253 kauth_cred_geteuid(l->l_cred) : -1);
254 sig = SIGKILL; 254 sig = SIGKILL;
255 } else { 255 code = SI_NOINFO;
 256 break;
 257 case EINVAL:
 258 code = BUS_ADRERR;
 259 sig = SIGBUS;
 260 break;
 261 case EACCES:
 262 code = SEGV_ACCERR;
256 sig = SIGSEGV; 263 sig = SIGSEGV;
257 if (rv != EACCES) 264 break;
258 code = SEGV_MAPERR; 265 default:
 266 code = SEGV_MAPERR;
 267 sig = SIGSEGV;
 268 break;
259 } 269 }
260 } else { 270 } else {
261 trapsig = false; 271 trapsig = false;
262 if (map != kernel_map && addr > 0 272 if (map != kernel_map && addr > 0
263 && (void *)addr >= vm->vm_maxsaddr) 273 && (void *)addr >= vm->vm_maxsaddr)
264 uvm_grow(p, addr); 274 uvm_grow(p, addr);
265 } 275 }
266 break; 276 break;
267 277
268 case T_BPTFLT|T_USER: 278 case T_BPTFLT|T_USER:
269 sig = SIGTRAP; 279 sig = SIGTRAP;
270 code = TRAP_BRKPT; 280 code = TRAP_BRKPT;
271 break; 281 break;
272 case T_TRCTRAP|T_USER: 282 case T_TRCTRAP|T_USER:
273 sig = SIGTRAP; 283 sig = SIGTRAP;
274 code = TRAP_TRACE; 284 code = TRAP_TRACE;
275 tf->tf_psl &= ~PSL_T; 285 tf->tf_psl &= ~PSL_T;
276 break; 286 break;
277 287
278 case T_PRIVINFLT|T_USER: 288 case T_PRIVINFLT|T_USER:
279 sig = SIGILL; 289 sig = SIGILL;
280 code = ILL_PRVOPC; 290 code = ILL_PRVOPC;
281 break; 291 break;
282 case T_RESADFLT|T_USER: 292 case T_RESADFLT|T_USER:
283 sig = SIGILL; 293 sig = SIGILL;
284 code = ILL_ILLADR; 294 code = ILL_ILLADR;
285 break; 295 break;
286 case T_RESOPFLT|T_USER: 296 case T_RESOPFLT|T_USER:
287 sig = SIGILL; 297 sig = SIGILL;
288 code = ILL_ILLOPC; 298 code = ILL_ILLOPC;
289 break; 299 break;
290 300
291 case T_XFCFLT|T_USER: 301 case T_XFCFLT|T_USER:
292 sig = SIGEMT; 302 sig = SIGEMT;
293 break; 303 break;
294 304
295 case T_ARITHFLT|T_USER: 305 case T_ARITHFLT|T_USER:
296 sig = SIGFPE; 306 sig = SIGFPE;
297 switch (tf->tf_code) { 307 switch (tf->tf_code) {
298 case ATRP_INTOVF: code = FPE_INTOVF; break; 308 case ATRP_INTOVF: code = FPE_INTOVF; break;
299 case ATRP_INTDIV: code = FPE_INTDIV; break; 309 case ATRP_INTDIV: code = FPE_INTDIV; break;
300 case ATRP_FLTOVF: code = FPE_FLTOVF; break; 310 case ATRP_FLTOVF: code = FPE_FLTOVF; break;
301 case ATRP_FLTDIV: code = FPE_FLTDIV; break; 311 case ATRP_FLTDIV: code = FPE_FLTDIV; break;
302 case ATRP_FLTUND: code = FPE_FLTUND; break; 312 case ATRP_FLTUND: code = FPE_FLTUND; break;
303 case ATRP_DECOVF: code = FPE_INTOVF; break; 313 case ATRP_DECOVF: code = FPE_INTOVF; break;
304 case ATRP_FLTSUB: code = FPE_FLTSUB; break; 314 case ATRP_FLTSUB: code = FPE_FLTSUB; break;
305 case AFLT_FLTDIV: code = FPE_FLTDIV; break; 315 case AFLT_FLTDIV: code = FPE_FLTDIV; break;
306 case AFLT_FLTUND: code = FPE_FLTUND; break; 316 case AFLT_FLTUND: code = FPE_FLTUND; break;
307 case AFLT_FLTOVF: code = FPE_FLTOVF; break; 317 case AFLT_FLTOVF: code = FPE_FLTOVF; break;
308 default: code = FPE_FLTINV; break; 318 default: code = FPE_FLTINV; break;
309 } 319 }
310 break; 320 break;
311 321
312 case T_ASTFLT|T_USER: 322 case T_ASTFLT|T_USER:
313 mtpr(AST_NO,PR_ASTLVL); 323 mtpr(AST_NO,PR_ASTLVL);
314 trapsig = false; 324 trapsig = false;
315 if (curcpu()->ci_want_resched) 325 if (curcpu()->ci_want_resched)
316 preempt(); 326 preempt();
317 break; 327 break;
318 328
319#ifdef DDB 329#ifdef DDB
320 case T_BPTFLT: /* Kernel breakpoint */ 330 case T_BPTFLT: /* Kernel breakpoint */
321 case T_KDBTRAP: 331 case T_KDBTRAP:
322 case T_KDBTRAP|T_USER: 332 case T_KDBTRAP|T_USER:
323 case T_TRCTRAP: 333 case T_TRCTRAP:
324 kdb_trap(tf); 334 kdb_trap(tf);
325 return; 335 return;
326#endif 336#endif
327 } 337 }
328 if (trapsig) { 338 if (trapsig) {
329 ksiginfo_t ksi; 339 ksiginfo_t ksi;
330 if ((sig == SIGSEGV || sig == SIGILL) 340 if ((sig == SIGSEGV || sig == SIGILL)
331 && cpu_printfataltraps 341 && cpu_printfataltraps
332 && (p->p_slflag & PSL_TRACED) == 0 342 && (p->p_slflag & PSL_TRACED) == 0
333 && !sigismember(&p->p_sigctx.ps_sigcatch, sig)) 343 && !sigismember(&p->p_sigctx.ps_sigcatch, sig))
334 printf("pid %d.%d (%s): sig %d: type %lx, code %lx, pc %lx, psl %lx\n", 344 printf("pid %d.%d (%s): sig %d: type %lx, code %lx, pc %lx, psl %lx\n",
335 p->p_pid, l->l_lid, p->p_comm, sig, tf->tf_trap, 345 p->p_pid, l->l_lid, p->p_comm, sig, tf->tf_trap,
336 tf->tf_code, tf->tf_pc, tf->tf_psl); 346 tf->tf_code, tf->tf_pc, tf->tf_psl);
337 KSI_INIT_TRAP(&ksi); 347 KSI_INIT_TRAP(&ksi);
338 ksi.ksi_signo = sig; 348 ksi.ksi_signo = sig;
339 ksi.ksi_trap = tf->tf_trap; 349 ksi.ksi_trap = tf->tf_trap;
340 ksi.ksi_addr = (void *)tf->tf_code; 350 ksi.ksi_addr = (void *)tf->tf_code;
341 ksi.ksi_code = code; 351 ksi.ksi_code = code;
342 352
343 /* 353 /*
344 * Arithmetic exceptions can be of two kinds: 354 * Arithmetic exceptions can be of two kinds:
345 * - traps (codes 1..7), where pc points to the 355 * - traps (codes 1..7), where pc points to the
346 * next instruction to execute. 356 * next instruction to execute.
347 * - faults (codes 8..10), where pc points to the 357 * - faults (codes 8..10), where pc points to the
348 * faulting instruction. 358 * faulting instruction.
349 * In the latter case, we need to advance pc by ourselves 359 * In the latter case, we need to advance pc by ourselves
350 * to prevent a signal loop. 360 * to prevent a signal loop.
351 * 361 *
352 * XXX this is gross -- miod 362 * XXX this is gross -- miod
353 */ 363 */
354 if (type == (T_ARITHFLT | T_USER) && (tf->tf_code & 8)) 364 if (type == (T_ARITHFLT | T_USER) && (tf->tf_code & 8))
355 tf->tf_pc = skip_opcode(tf->tf_pc); 365 tf->tf_pc = skip_opcode(tf->tf_pc);
356 366
357 trapsignal(l, &ksi); 367 trapsignal(l, &ksi);
358 } 368 }
359 369
360 if (!usermode) 370 if (!usermode)
361 return; 371 return;
362 372
363 userret(l, tf, oticks); 373 userret(l, tf, oticks);
364} 374}
365 375
366void 376void
367setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 377setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
368{ 378{
369 struct trapframe * const tf = l->l_md.md_utf; 379 struct trapframe * const tf = l->l_md.md_utf;
370 380
371 tf->tf_pc = pack->ep_entry + 2; 381 tf->tf_pc = pack->ep_entry + 2;
372 tf->tf_sp = stack; 382 tf->tf_sp = stack;
373 tf->tf_r6 = stack; /* for ELF */ 383 tf->tf_r6 = stack; /* for ELF */
374 tf->tf_r7 = 0; /* for ELF */ 384 tf->tf_r7 = 0; /* for ELF */
375 tf->tf_r8 = 0; /* for ELF */ 385 tf->tf_r8 = 0; /* for ELF */
376 tf->tf_r9 = l->l_proc->p_psstrp; /* for ELF */ 386 tf->tf_r9 = l->l_proc->p_psstrp; /* for ELF */
377} 387}
378 388
379 389
380/*  390/*
381 * Start a new LWP 391 * Start a new LWP
382 */ 392 */
383void 393void
384startlwp(void *arg) 394startlwp(void *arg)
385{ 395{
386 ucontext_t * const uc = arg; 396 ucontext_t * const uc = arg;
387 lwp_t * const l = curlwp; 397 lwp_t * const l = curlwp;
388 int error __diagused; 398 int error __diagused;
389 399
390 error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags); 400 error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
391 KASSERT(error == 0); 401 KASSERT(error == 0);
392 402
393 kmem_free(uc, sizeof(ucontext_t)); 403 kmem_free(uc, sizeof(ucontext_t));
394 /* XXX - profiling spoiled here */ 404 /* XXX - profiling spoiled here */
395 userret(l, l->l_md.md_utf, l->l_proc->p_sticks); 405 userret(l, l->l_md.md_utf, l->l_proc->p_sticks);
396} 406}