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