1 /* $NetBSD: trap.c,v 1.132 2013/10/25 16:30:52 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.132 2013/10/25 16:30:52 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 code = SEGV_ACCERR; 248 if (rv == 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 } else { 256 sig = SIGSEGV; 257 if (rv != EACCES) 258 code = SEGV_MAPERR; 259 } 260 } else { 261 trapsig = false; 262 if (map != kernel_map && addr > 0 263 && (void *)addr >= vm->vm_maxsaddr) 264 uvm_grow(p, addr); 265 } 266 break; 267 268 case T_BPTFLT|T_USER: 269 sig = SIGTRAP; 270 code = TRAP_BRKPT; 271 break; 272 case T_TRCTRAP|T_USER: 273 sig = SIGTRAP; 274 code = TRAP_TRACE; 275 tf->tf_psl &= ~PSL_T; 276 break; 277 278 case T_PRIVINFLT|T_USER: 279 sig = SIGILL; 280 code = ILL_PRVOPC; 281 break; 282 case T_RESADFLT|T_USER: 283 sig = SIGILL; 284 code = ILL_ILLADR; 285 break; 286 case T_RESOPFLT|T_USER: 287 sig = SIGILL; 288 code = ILL_ILLOPC; 289 break; 290 291 case T_XFCFLT|T_USER: 292 sig = SIGEMT; 293 break; 294 295 case T_ARITHFLT|T_USER: 296 sig = SIGFPE; 297 switch (tf->tf_code) { 298 case ATRP_INTOVF: code = FPE_INTOVF; break; 299 case ATRP_INTDIV: code = FPE_INTDIV; break; 300 case ATRP_FLTOVF: code = FPE_FLTOVF; break; 301 case ATRP_FLTDIV: code = FPE_FLTDIV; break; 302 case ATRP_FLTUND: code = FPE_FLTUND; break; 303 case ATRP_DECOVF: code = FPE_INTOVF; break; 304 case ATRP_FLTSUB: code = FPE_FLTSUB; break; 305 case AFLT_FLTDIV: code = FPE_FLTDIV; break; 306 case AFLT_FLTUND: code = FPE_FLTUND; break; 307 case AFLT_FLTOVF: code = FPE_FLTOVF; break; 308 default: code = FPE_FLTINV; break; 309 } 310 break; 311 312 case T_ASTFLT|T_USER: 313 mtpr(AST_NO,PR_ASTLVL); 314 trapsig = false; 315 if (curcpu()->ci_want_resched) 316 preempt(); 317 break; 318 319 #ifdef DDB 320 case T_BPTFLT: /* Kernel breakpoint */ 321 case T_KDBTRAP: 322 case T_KDBTRAP|T_USER: 323 case T_TRCTRAP: 324 kdb_trap(tf); 325 return; 326 #endif 327 } 328 if (trapsig) { 329 ksiginfo_t ksi; 330 if ((sig == SIGSEGV || sig == SIGILL) 331 && cpu_printfataltraps 332 && (p->p_slflag & PSL_TRACED) == 0 333 && !sigismember(&p->p_sigctx.ps_sigcatch, sig)) 334 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, 336 tf->tf_code, tf->tf_pc, tf->tf_psl); 337 KSI_INIT_TRAP(&ksi); 338 ksi.ksi_signo = sig; 339 ksi.ksi_trap = tf->tf_trap; 340 ksi.ksi_addr = (void *)tf->tf_code; 341 ksi.ksi_code = code; 342 343 /* 344 * Arithmetic exceptions can be of two kinds: 345 * - traps (codes 1..7), where pc points to the 346 * next instruction to execute. 347 * - faults (codes 8..10), where pc points to the 348 * faulting instruction. 349 * In the latter case, we need to advance pc by ourselves 350 * to prevent a signal loop. 351 * 352 * XXX this is gross -- miod 353 */ 354 if (type == (T_ARITHFLT | T_USER) && (tf->tf_code & 8)) 355 tf->tf_pc = skip_opcode(tf->tf_pc); 356 357 trapsignal(l, &ksi); 358 } 359 360 if (!usermode) 361 return; 362 363 userret(l, tf, oticks); 364 } 365 366 void 367 setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack) 368 { 369 struct trapframe * const tf = l->l_md.md_utf; 370 371 tf->tf_pc = pack->ep_entry + 2; 372 tf->tf_sp = stack; 373 tf->tf_r6 = stack; /* for ELF */ 374 tf->tf_r7 = 0; /* for ELF */ 375 tf->tf_r8 = 0; /* for ELF */ 376 tf->tf_r9 = l->l_proc->p_psstrp; /* for ELF */ 377 } 378 379 380 /* 381 * Start a new LWP 382 */ 383 void 384 startlwp(void *arg) 385 { 386 ucontext_t * const uc = arg; 387 lwp_t * const l = curlwp; 388 int error __diagused; 389 390 error = cpu_setmcontext(l, &uc->uc_mcontext, uc->uc_flags); 391 KASSERT(error == 0); 392 393 kmem_free(uc, sizeof(ucontext_t)); 394 /* XXX - profiling spoiled here */ 395 userret(l, l->l_md.md_utf, l->l_proc->p_sticks); 396 } 397