trap.c revision 240244
1/* $OpenBSD: trap.c,v 1.19 1998/09/30 12:40:41 pefo Exp $ */ 2/* tracked to 1.23 */ 3/*- 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department and Ralph Campbell. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: Utah Hdr: trap.c 1.32 91/04/06 37 * 38 * from: @(#)trap.c 8.5 (Berkeley) 1/11/94 39 * JNPR: trap.c,v 1.13.2.2 2007/08/29 10:03:49 girish 40 */ 41#include <sys/cdefs.h> 42__FBSDID("$FreeBSD: head/sys/mips/mips/trap.c 240244 2012-09-08 18:27:11Z attilio $"); 43 44#include "opt_compat.h" 45#include "opt_ddb.h" 46#include "opt_global.h" 47#include "opt_ktrace.h" 48#include "opt_kdtrace.h" 49 50#define NO_REG_DEFS 1 /* Prevent asm.h from including regdef.h */ 51#include <sys/param.h> 52#include <sys/systm.h> 53#include <sys/sysent.h> 54#include <sys/proc.h> 55#include <sys/kernel.h> 56#include <sys/signalvar.h> 57#include <sys/syscall.h> 58#include <sys/lock.h> 59#include <vm/vm.h> 60#include <vm/vm_extern.h> 61#include <vm/vm_kern.h> 62#include <vm/vm_page.h> 63#include <vm/vm_map.h> 64#include <vm/vm_param.h> 65#include <sys/vmmeter.h> 66#include <sys/ptrace.h> 67#include <sys/user.h> 68#include <sys/buf.h> 69#include <sys/vnode.h> 70#include <sys/pioctl.h> 71#include <sys/sysctl.h> 72#include <sys/syslog.h> 73#include <sys/bus.h> 74#ifdef KTRACE 75#include <sys/ktrace.h> 76#endif 77#include <net/netisr.h> 78 79#include <machine/trap.h> 80#include <machine/cpu.h> 81#include <machine/pte.h> 82#include <machine/pmap.h> 83#include <machine/md_var.h> 84#include <machine/mips_opcode.h> 85#include <machine/frame.h> 86#include <machine/regnum.h> 87#include <machine/tls.h> 88#include <machine/asm.h> 89 90#ifdef DDB 91#include <machine/db_machdep.h> 92#include <ddb/db_sym.h> 93#include <ddb/ddb.h> 94#include <sys/kdb.h> 95#endif 96 97#ifdef KDTRACE_HOOKS 98#include <sys/dtrace_bsd.h> 99 100/* 101 * This is a hook which is initialised by the dtrace module 102 * to handle traps which might occur during DTrace probe 103 * execution. 104 */ 105dtrace_trap_func_t dtrace_trap_func; 106 107dtrace_doubletrap_func_t dtrace_doubletrap_func; 108 109/* 110 * This is a hook which is initialised by the systrace module 111 * when it is loaded. This keeps the DTrace syscall provider 112 * implementation opaque. 113 */ 114systrace_probe_func_t systrace_probe_func; 115 116/* 117 * These hooks are necessary for the pid, usdt and fasttrap providers. 118 */ 119dtrace_fasttrap_probe_ptr_t dtrace_fasttrap_probe_ptr; 120dtrace_pid_probe_ptr_t dtrace_pid_probe_ptr; 121dtrace_return_probe_ptr_t dtrace_return_probe_ptr; 122#endif 123 124#ifdef TRAP_DEBUG 125int trap_debug = 0; 126SYSCTL_INT(_machdep, OID_AUTO, trap_debug, CTLFLAG_RW, 127 &trap_debug, 0, "Debug information on all traps"); 128#endif 129 130static void log_illegal_instruction(const char *, struct trapframe *); 131static void log_bad_page_fault(char *, struct trapframe *, int); 132static void log_frame_dump(struct trapframe *frame); 133static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **); 134 135#ifdef TRAP_DEBUG 136static void trap_frame_dump(struct trapframe *frame); 137#endif 138 139void (*machExceptionTable[]) (void)= { 140/* 141 * The kernel exception handlers. 142 */ 143 MipsKernIntr, /* external interrupt */ 144 MipsKernGenException, /* TLB modification */ 145 MipsTLBInvalidException,/* TLB miss (load or instr. fetch) */ 146 MipsTLBInvalidException,/* TLB miss (store) */ 147 MipsKernGenException, /* address error (load or I-fetch) */ 148 MipsKernGenException, /* address error (store) */ 149 MipsKernGenException, /* bus error (I-fetch) */ 150 MipsKernGenException, /* bus error (load or store) */ 151 MipsKernGenException, /* system call */ 152 MipsKernGenException, /* breakpoint */ 153 MipsKernGenException, /* reserved instruction */ 154 MipsKernGenException, /* coprocessor unusable */ 155 MipsKernGenException, /* arithmetic overflow */ 156 MipsKernGenException, /* trap exception */ 157 MipsKernGenException, /* virtual coherence exception inst */ 158 MipsKernGenException, /* floating point exception */ 159 MipsKernGenException, /* reserved */ 160 MipsKernGenException, /* reserved */ 161 MipsKernGenException, /* reserved */ 162 MipsKernGenException, /* reserved */ 163 MipsKernGenException, /* reserved */ 164 MipsKernGenException, /* reserved */ 165 MipsKernGenException, /* reserved */ 166 MipsKernGenException, /* watch exception */ 167 MipsKernGenException, /* reserved */ 168 MipsKernGenException, /* reserved */ 169 MipsKernGenException, /* reserved */ 170 MipsKernGenException, /* reserved */ 171 MipsKernGenException, /* reserved */ 172 MipsKernGenException, /* reserved */ 173 MipsKernGenException, /* reserved */ 174 MipsKernGenException, /* virtual coherence exception data */ 175/* 176 * The user exception handlers. 177 */ 178 MipsUserIntr, /* 0 */ 179 MipsUserGenException, /* 1 */ 180 MipsTLBInvalidException,/* 2 */ 181 MipsTLBInvalidException,/* 3 */ 182 MipsUserGenException, /* 4 */ 183 MipsUserGenException, /* 5 */ 184 MipsUserGenException, /* 6 */ 185 MipsUserGenException, /* 7 */ 186 MipsUserGenException, /* 8 */ 187 MipsUserGenException, /* 9 */ 188 MipsUserGenException, /* 10 */ 189 MipsUserGenException, /* 11 */ 190 MipsUserGenException, /* 12 */ 191 MipsUserGenException, /* 13 */ 192 MipsUserGenException, /* 14 */ 193 MipsUserGenException, /* 15 */ 194 MipsUserGenException, /* 16 */ 195 MipsUserGenException, /* 17 */ 196 MipsUserGenException, /* 18 */ 197 MipsUserGenException, /* 19 */ 198 MipsUserGenException, /* 20 */ 199 MipsUserGenException, /* 21 */ 200 MipsUserGenException, /* 22 */ 201 MipsUserGenException, /* 23 */ 202 MipsUserGenException, /* 24 */ 203 MipsUserGenException, /* 25 */ 204 MipsUserGenException, /* 26 */ 205 MipsUserGenException, /* 27 */ 206 MipsUserGenException, /* 28 */ 207 MipsUserGenException, /* 29 */ 208 MipsUserGenException, /* 20 */ 209 MipsUserGenException, /* 31 */ 210}; 211 212char *trap_type[] = { 213 "external interrupt", 214 "TLB modification", 215 "TLB miss (load or instr. fetch)", 216 "TLB miss (store)", 217 "address error (load or I-fetch)", 218 "address error (store)", 219 "bus error (I-fetch)", 220 "bus error (load or store)", 221 "system call", 222 "breakpoint", 223 "reserved instruction", 224 "coprocessor unusable", 225 "arithmetic overflow", 226 "trap", 227 "virtual coherency instruction", 228 "floating point", 229 "reserved 16", 230 "reserved 17", 231 "reserved 18", 232 "reserved 19", 233 "reserved 20", 234 "reserved 21", 235 "reserved 22", 236 "watch", 237 "reserved 24", 238 "reserved 25", 239 "reserved 26", 240 "reserved 27", 241 "reserved 28", 242 "reserved 29", 243 "reserved 30", 244 "virtual coherency data", 245}; 246 247#if !defined(SMP) && (defined(DDB) || defined(DEBUG)) 248struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug; 249#endif 250 251#if defined(DDB) || defined(DEBUG) 252void stacktrace(struct trapframe *); 253void logstacktrace(struct trapframe *); 254#endif 255 256#define KERNLAND(x) ((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS) 257#define DELAYBRANCH(x) ((int)(x) < 0) 258 259/* 260 * MIPS load/store access type 261 */ 262enum { 263 MIPS_LHU_ACCESS = 1, 264 MIPS_LH_ACCESS, 265 MIPS_LWU_ACCESS, 266 MIPS_LW_ACCESS, 267 MIPS_LD_ACCESS, 268 MIPS_SH_ACCESS, 269 MIPS_SW_ACCESS, 270 MIPS_SD_ACCESS 271}; 272 273char *access_name[] = { 274 "Load Halfword Unsigned", 275 "Load Halfword", 276 "Load Word Unsigned", 277 "Load Word", 278 "Load Doubleword", 279 "Store Halfword", 280 "Store Word", 281 "Store Doubleword" 282}; 283 284#ifdef CPU_CNMIPS 285#include <machine/octeon_cop2.h> 286#endif 287 288static int allow_unaligned_acc = 1; 289 290SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW, 291 &allow_unaligned_acc, 0, "Allow unaligned accesses"); 292 293/* 294 * FP emulation is assumed to work on O32, but the code is outdated and crufty 295 * enough that it's a more sensible default to have it disabled when using 296 * other ABIs. At the very least, it needs a lot of help in using 297 * type-semantic ABI-oblivious macros for everything it does. 298 */ 299#if defined(__mips_o32) 300static int emulate_fp = 1; 301#else 302static int emulate_fp = 0; 303#endif 304SYSCTL_INT(_machdep, OID_AUTO, emulate_fp, CTLFLAG_RW, 305 &emulate_fp, 0, "Emulate unimplemented FPU instructions"); 306 307static int emulate_unaligned_access(struct trapframe *frame, int mode); 308 309extern void fswintrberr(void); /* XXX */ 310 311int 312cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 313{ 314 struct trapframe *locr0 = td->td_frame; 315 struct sysentvec *se; 316 int error, nsaved; 317 318 bzero(sa->args, sizeof(sa->args)); 319 320 /* compute next PC after syscall instruction */ 321 td->td_pcb->pcb_tpc = sa->trapframe->pc; /* Remember if restart */ 322 if (DELAYBRANCH(sa->trapframe->cause)) /* Check BD bit */ 323 locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0); 324 else 325 locr0->pc += sizeof(int); 326 sa->code = locr0->v0; 327 328 switch (sa->code) { 329 case SYS___syscall: 330 case SYS_syscall: 331 /* 332 * This is an indirect syscall, in which the code is the first argument. 333 */ 334#if (!defined(__mips_n32) && !defined(__mips_n64)) || defined(COMPAT_FREEBSD32) 335 if (sa->code == SYS___syscall && SV_PROC_FLAG(td->td_proc, SV_ILP32)) { 336 /* 337 * Like syscall, but code is a quad, so as to maintain alignment 338 * for the rest of the arguments. 339 */ 340 if (_QUAD_LOWWORD == 0) 341 sa->code = locr0->a0; 342 else 343 sa->code = locr0->a1; 344 sa->args[0] = locr0->a2; 345 sa->args[1] = locr0->a3; 346 nsaved = 2; 347 break; 348 } 349#endif 350 /* 351 * This is either not a quad syscall, or is a quad syscall with a 352 * new ABI in which quads fit in a single register. 353 */ 354 sa->code = locr0->a0; 355 sa->args[0] = locr0->a1; 356 sa->args[1] = locr0->a2; 357 sa->args[2] = locr0->a3; 358 nsaved = 3; 359#if defined(__mips_n32) || defined(__mips_n64) 360#ifdef COMPAT_FREEBSD32 361 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) { 362#endif 363 /* 364 * Non-o32 ABIs support more arguments in registers. 365 */ 366 sa->args[3] = locr0->t4; 367 sa->args[4] = locr0->t5; 368 sa->args[5] = locr0->t6; 369 sa->args[6] = locr0->t7; 370 nsaved += 4; 371#ifdef COMPAT_FREEBSD32 372 } 373#endif 374#endif 375 break; 376 default: 377 /* 378 * A direct syscall, arguments are just parameters to the syscall. 379 */ 380 sa->args[0] = locr0->a0; 381 sa->args[1] = locr0->a1; 382 sa->args[2] = locr0->a2; 383 sa->args[3] = locr0->a3; 384 nsaved = 4; 385#if defined (__mips_n32) || defined(__mips_n64) 386#ifdef COMPAT_FREEBSD32 387 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) { 388#endif 389 /* 390 * Non-o32 ABIs support more arguments in registers. 391 */ 392 sa->args[4] = locr0->t4; 393 sa->args[5] = locr0->t5; 394 sa->args[6] = locr0->t6; 395 sa->args[7] = locr0->t7; 396 nsaved += 4; 397#ifdef COMPAT_FREEBSD32 398 } 399#endif 400#endif 401 break; 402 } 403 404#ifdef TRAP_DEBUG 405 if (trap_debug) 406 printf("SYSCALL #%d pid:%u\n", sa->code, td->td_proc->p_pid); 407#endif 408 409 se = td->td_proc->p_sysent; 410 /* 411 * XXX 412 * Shouldn't this go before switching on the code? 413 */ 414 if (se->sv_mask) 415 sa->code &= se->sv_mask; 416 417 if (sa->code >= se->sv_size) 418 sa->callp = &se->sv_table[0]; 419 else 420 sa->callp = &se->sv_table[sa->code]; 421 422 sa->narg = sa->callp->sy_narg; 423 424 if (sa->narg > nsaved) { 425#if defined(__mips_n32) || defined(__mips_n64) 426 /* 427 * XXX 428 * Is this right for new ABIs? I think the 4 there 429 * should be 8, size there are 8 registers to skip, 430 * not 4, but I'm not certain. 431 */ 432#ifdef COMPAT_FREEBSD32 433 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)) 434#endif 435 printf("SYSCALL #%u pid:%u, narg (%u) > nsaved (%u).\n", 436 sa->code, td->td_proc->p_pid, sa->narg, nsaved); 437#endif 438#if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32) 439 if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) { 440 unsigned i; 441 int32_t arg; 442 443 error = 0; /* XXX GCC is awful. */ 444 for (i = nsaved; i < sa->narg; i++) { 445 error = copyin((caddr_t)(intptr_t)(locr0->sp + 446 (4 + (i - nsaved)) * sizeof(int32_t)), 447 (caddr_t)&arg, sizeof arg); 448 if (error != 0) 449 break; 450 sa->args[i] = arg; 451 } 452 } else 453#endif 454 error = copyin((caddr_t)(intptr_t)(locr0->sp + 455 4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved], 456 (u_int)(sa->narg - nsaved) * sizeof(register_t)); 457 if (error != 0) { 458 locr0->v0 = error; 459 locr0->a3 = 1; 460 } 461 } else 462 error = 0; 463 464 if (error == 0) { 465 td->td_retval[0] = 0; 466 td->td_retval[1] = locr0->v1; 467 } 468 469 return (error); 470} 471 472#undef __FBSDID 473#define __FBSDID(x) 474#include "../../kern/subr_syscall.c" 475 476/* 477 * Handle an exception. 478 * Called from MipsKernGenException() or MipsUserGenException() 479 * when a processor trap occurs. 480 * In the case of a kernel trap, we return the pc where to resume if 481 * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc. 482 */ 483register_t 484trap(struct trapframe *trapframe) 485{ 486 int type, usermode; 487 int i = 0; 488 unsigned ucode = 0; 489 struct thread *td = curthread; 490 struct proc *p = curproc; 491 vm_prot_t ftype; 492 pmap_t pmap; 493 int access_type; 494 ksiginfo_t ksi; 495 char *msg = NULL; 496 intptr_t addr = 0; 497 register_t pc; 498 int cop; 499 register_t *frame_regs; 500 501 trapdebug_enter(trapframe, 0); 502 503 type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT; 504 if (TRAPF_USERMODE(trapframe)) { 505 type |= T_USER; 506 usermode = 1; 507 } else { 508 usermode = 0; 509 } 510 511 /* 512 * Enable hardware interrupts if they were on before the trap. If it 513 * was off disable all so we don't accidently enable it when doing a 514 * return to userland. 515 */ 516 if (trapframe->sr & MIPS_SR_INT_IE) { 517 set_intr_mask(trapframe->sr & MIPS_SR_INT_MASK); 518 intr_enable(); 519 } else { 520 intr_disable(); 521 } 522 523#ifdef TRAP_DEBUG 524 if (trap_debug) { 525 static vm_offset_t last_badvaddr = 0; 526 static vm_offset_t this_badvaddr = 0; 527 static int count = 0; 528 u_int32_t pid; 529 530 printf("trap type %x (%s - ", type, 531 trap_type[type & (~T_USER)]); 532 533 if (type & T_USER) 534 printf("user mode)\n"); 535 else 536 printf("kernel mode)\n"); 537 538#ifdef SMP 539 printf("cpuid = %d\n", PCPU_GET(cpuid)); 540#endif 541 pid = mips_rd_entryhi() & TLBHI_ASID_MASK; 542 printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n", 543 (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra, 544 (intmax_t)trapframe->sp, (intmax_t)trapframe->sr, 545 (curproc ? curproc->p_pid : -1), pid); 546 547 switch (type & ~T_USER) { 548 case T_TLB_MOD: 549 case T_TLB_LD_MISS: 550 case T_TLB_ST_MISS: 551 case T_ADDR_ERR_LD: 552 case T_ADDR_ERR_ST: 553 this_badvaddr = trapframe->badvaddr; 554 break; 555 case T_SYSCALL: 556 this_badvaddr = trapframe->ra; 557 break; 558 default: 559 this_badvaddr = trapframe->pc; 560 break; 561 } 562 if ((last_badvaddr == this_badvaddr) && 563 ((type & ~T_USER) != T_SYSCALL)) { 564 if (++count == 3) { 565 trap_frame_dump(trapframe); 566 panic("too many faults at %p\n", (void *)last_badvaddr); 567 } 568 } else { 569 last_badvaddr = this_badvaddr; 570 count = 0; 571 } 572 } 573#endif 574 575#ifdef KDTRACE_HOOKS 576 /* 577 * A trap can occur while DTrace executes a probe. Before 578 * executing the probe, DTrace blocks re-scheduling and sets 579 * a flag in it's per-cpu flags to indicate that it doesn't 580 * want to fault. On returning from the probe, the no-fault 581 * flag is cleared and finally re-scheduling is enabled. 582 * 583 * If the DTrace kernel module has registered a trap handler, 584 * call it and if it returns non-zero, assume that it has 585 * handled the trap and modified the trap frame so that this 586 * function can return normally. 587 */ 588 /* 589 * XXXDTRACE: add fasttrap and pid probes handlers here (if ever) 590 */ 591 if (!usermode) { 592 if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe, type)) 593 return (trapframe->pc); 594 } 595#endif 596 597 switch (type) { 598 case T_MCHECK: 599#ifdef DDB 600 kdb_trap(type, 0, trapframe); 601#endif 602 panic("MCHECK\n"); 603 break; 604 case T_TLB_MOD: 605 /* check for kernel address */ 606 if (KERNLAND(trapframe->badvaddr)) { 607 if (pmap_emulate_modified(kernel_pmap, 608 trapframe->badvaddr) != 0) { 609 ftype = VM_PROT_WRITE; 610 goto kernel_fault; 611 } 612 return (trapframe->pc); 613 } 614 /* FALLTHROUGH */ 615 616 case T_TLB_MOD + T_USER: 617 pmap = &p->p_vmspace->vm_pmap; 618 if (pmap_emulate_modified(pmap, trapframe->badvaddr) != 0) { 619 ftype = VM_PROT_WRITE; 620 goto dofault; 621 } 622 if (!usermode) 623 return (trapframe->pc); 624 goto out; 625 626 case T_TLB_LD_MISS: 627 case T_TLB_ST_MISS: 628 ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ; 629 /* check for kernel address */ 630 if (KERNLAND(trapframe->badvaddr)) { 631 vm_offset_t va; 632 int rv; 633 634 kernel_fault: 635 va = trunc_page((vm_offset_t)trapframe->badvaddr); 636 rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL); 637 if (rv == KERN_SUCCESS) 638 return (trapframe->pc); 639 if (td->td_pcb->pcb_onfault != NULL) { 640 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; 641 td->td_pcb->pcb_onfault = NULL; 642 return (pc); 643 } 644 goto err; 645 } 646 647 /* 648 * It is an error for the kernel to access user space except 649 * through the copyin/copyout routines. 650 */ 651 if (td->td_pcb->pcb_onfault == NULL) 652 goto err; 653 654 /* check for fuswintr() or suswintr() getting a page fault */ 655 /* XXX There must be a nicer way to do this. */ 656 if (td->td_pcb->pcb_onfault == fswintrberr) { 657 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; 658 td->td_pcb->pcb_onfault = NULL; 659 return (pc); 660 } 661 662 goto dofault; 663 664 case T_TLB_LD_MISS + T_USER: 665 ftype = VM_PROT_READ; 666 goto dofault; 667 668 case T_TLB_ST_MISS + T_USER: 669 ftype = VM_PROT_WRITE; 670dofault: 671 { 672 vm_offset_t va; 673 struct vmspace *vm; 674 vm_map_t map; 675 int rv = 0; 676 677 vm = p->p_vmspace; 678 map = &vm->vm_map; 679 va = trunc_page((vm_offset_t)trapframe->badvaddr); 680 if (KERNLAND(trapframe->badvaddr)) { 681 /* 682 * Don't allow user-mode faults in kernel 683 * address space. 684 */ 685 goto nogo; 686 } 687 688 /* 689 * Keep swapout from messing with us during this 690 * critical time. 691 */ 692 PROC_LOCK(p); 693 ++p->p_lock; 694 PROC_UNLOCK(p); 695 696 rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL); 697 698 PROC_LOCK(p); 699 --p->p_lock; 700 PROC_UNLOCK(p); 701 /* 702 * XXXDTRACE: add dtrace_doubletrap_func here? 703 */ 704#ifdef VMFAULT_TRACE 705 printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n", 706 map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr, 707 ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc); 708#endif 709 710 if (rv == KERN_SUCCESS) { 711 if (!usermode) { 712 return (trapframe->pc); 713 } 714 goto out; 715 } 716 nogo: 717 if (!usermode) { 718 if (td->td_pcb->pcb_onfault != NULL) { 719 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; 720 td->td_pcb->pcb_onfault = NULL; 721 return (pc); 722 } 723 goto err; 724 } 725 ucode = ftype; 726 i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); 727 addr = trapframe->pc; 728 729 msg = "BAD_PAGE_FAULT"; 730 log_bad_page_fault(msg, trapframe, type); 731 732 break; 733 } 734 735 case T_ADDR_ERR_LD + T_USER: /* misaligned or kseg access */ 736 case T_ADDR_ERR_ST + T_USER: /* misaligned or kseg access */ 737 if (trapframe->badvaddr < 0 || 738 trapframe->badvaddr >= VM_MAXUSER_ADDRESS) { 739 msg = "ADDRESS_SPACE_ERR"; 740 } else if (allow_unaligned_acc) { 741 int mode; 742 743 if (type == (T_ADDR_ERR_LD + T_USER)) 744 mode = VM_PROT_READ; 745 else 746 mode = VM_PROT_WRITE; 747 748 access_type = emulate_unaligned_access(trapframe, mode); 749 if (access_type != 0) 750 goto out; 751 msg = "ALIGNMENT_FIX_ERR"; 752 } else { 753 msg = "ADDRESS_ERR"; 754 } 755 756 /* FALL THROUGH */ 757 758 case T_BUS_ERR_IFETCH + T_USER: /* BERR asserted to cpu */ 759 case T_BUS_ERR_LD_ST + T_USER: /* BERR asserted to cpu */ 760 ucode = 0; /* XXX should be VM_PROT_something */ 761 i = SIGBUS; 762 addr = trapframe->pc; 763 if (!msg) 764 msg = "BUS_ERR"; 765 log_bad_page_fault(msg, trapframe, type); 766 break; 767 768 case T_SYSCALL + T_USER: 769 { 770 struct syscall_args sa; 771 int error; 772 773 sa.trapframe = trapframe; 774 error = syscallenter(td, &sa); 775 776#if !defined(SMP) && (defined(DDB) || defined(DEBUG)) 777 if (trp == trapdebug) 778 trapdebug[TRAPSIZE - 1].code = sa.code; 779 else 780 trp[-1].code = sa.code; 781#endif 782 trapdebug_enter(td->td_frame, -sa.code); 783 784 /* 785 * The sync'ing of I & D caches for SYS_ptrace() is 786 * done by procfs_domem() through procfs_rwmem() 787 * instead of being done here under a special check 788 * for SYS_ptrace(). 789 */ 790 syscallret(td, error, &sa); 791 return (trapframe->pc); 792 } 793 794#ifdef DDB 795 case T_BREAK: 796 kdb_trap(type, 0, trapframe); 797 return (trapframe->pc); 798#endif 799 800 case T_BREAK + T_USER: 801 { 802 intptr_t va; 803 uint32_t instr; 804 805 /* compute address of break instruction */ 806 va = trapframe->pc; 807 if (DELAYBRANCH(trapframe->cause)) 808 va += sizeof(int); 809 810 /* read break instruction */ 811 instr = fuword32((caddr_t)va); 812#if 0 813 printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n", 814 p->p_comm, p->p_pid, instr, trapframe->pc, 815 p->p_md.md_ss_addr, p->p_md.md_ss_instr); /* XXX */ 816#endif 817 if (td->td_md.md_ss_addr != va || 818 instr != MIPS_BREAK_SSTEP) { 819 i = SIGTRAP; 820 addr = trapframe->pc; 821 break; 822 } 823 /* 824 * The restoration of the original instruction and 825 * the clearing of the berakpoint will be done later 826 * by the call to ptrace_clear_single_step() in 827 * issignal() when SIGTRAP is processed. 828 */ 829 addr = trapframe->pc; 830 i = SIGTRAP; 831 break; 832 } 833 834 case T_IWATCH + T_USER: 835 case T_DWATCH + T_USER: 836 { 837 intptr_t va; 838 839 /* compute address of trapped instruction */ 840 va = trapframe->pc; 841 if (DELAYBRANCH(trapframe->cause)) 842 va += sizeof(int); 843 printf("watch exception @ %p\n", (void *)va); 844 i = SIGTRAP; 845 addr = va; 846 break; 847 } 848 849 case T_TRAP + T_USER: 850 { 851 intptr_t va; 852 uint32_t instr; 853 struct trapframe *locr0 = td->td_frame; 854 855 /* compute address of trap instruction */ 856 va = trapframe->pc; 857 if (DELAYBRANCH(trapframe->cause)) 858 va += sizeof(int); 859 /* read break instruction */ 860 instr = fuword32((caddr_t)va); 861 862 if (DELAYBRANCH(trapframe->cause)) { /* Check BD bit */ 863 locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0, 864 0); 865 } else { 866 locr0->pc += sizeof(int); 867 } 868 addr = va; 869 i = SIGEMT; /* Stuff it with something for now */ 870 break; 871 } 872 873 case T_RES_INST + T_USER: 874 { 875 InstFmt inst; 876 inst = *(InstFmt *)(intptr_t)trapframe->pc; 877 switch (inst.RType.op) { 878 case OP_SPECIAL3: 879 switch (inst.RType.func) { 880 case OP_RDHWR: 881 /* Register 29 used for TLS */ 882 if (inst.RType.rd == 29) { 883 frame_regs = &(trapframe->zero); 884 frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls; 885#if defined(__mips_n64) && defined(COMPAT_FREEBSD32) 886 if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) 887 frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE32; 888 else 889#endif 890 frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE; 891 trapframe->pc += sizeof(int); 892 goto out; 893 } 894 break; 895 } 896 break; 897 } 898 899 log_illegal_instruction("RES_INST", trapframe); 900 i = SIGILL; 901 addr = trapframe->pc; 902 } 903 break; 904 case T_C2E: 905 case T_C2E + T_USER: 906 goto err; 907 break; 908 case T_COP_UNUSABLE: 909#ifdef CPU_CNMIPS 910 cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT; 911 /* Handle only COP2 exception */ 912 if (cop != 2) 913 goto err; 914 915 addr = trapframe->pc; 916 /* save userland cop2 context if it has been touched */ 917 if ((td->td_md.md_flags & MDTD_COP2USED) && 918 (td->td_md.md_cop2owner == COP2_OWNER_USERLAND)) { 919 if (td->td_md.md_ucop2) 920 octeon_cop2_save(td->td_md.md_ucop2); 921 else 922 panic("COP2 was used in user mode but md_ucop2 is NULL"); 923 } 924 925 if (td->td_md.md_cop2 == NULL) { 926 td->td_md.md_cop2 = octeon_cop2_alloc_ctx(); 927 if (td->td_md.md_cop2 == NULL) 928 panic("Failed to allocate COP2 context"); 929 memset(td->td_md.md_cop2, 0, sizeof(*td->td_md.md_cop2)); 930 } 931 932 octeon_cop2_restore(td->td_md.md_cop2); 933 934 /* Make userland re-request its context */ 935 td->td_frame->sr &= ~MIPS_SR_COP_2_BIT; 936 td->td_md.md_flags |= MDTD_COP2USED; 937 td->td_md.md_cop2owner = COP2_OWNER_KERNEL; 938 /* Enable COP2, it will be disabled in cpu_switch */ 939 mips_wr_status(mips_rd_status() | MIPS_SR_COP_2_BIT); 940 return (trapframe->pc); 941#else 942 goto err; 943 break; 944#endif 945 946 case T_COP_UNUSABLE + T_USER: 947 cop = (trapframe->cause & MIPS_CR_COP_ERR) >> MIPS_CR_COP_ERR_SHIFT; 948 if (cop == 1) { 949#if !defined(CPU_HAVEFPU) 950 /* FP (COP1) instruction */ 951 log_illegal_instruction("COP1_UNUSABLE", trapframe); 952 i = SIGILL; 953 break; 954#else 955 addr = trapframe->pc; 956 MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame); 957 PCPU_SET(fpcurthread, td); 958 td->td_frame->sr |= MIPS_SR_COP_1_BIT; 959 td->td_md.md_flags |= MDTD_FPUSED; 960 goto out; 961#endif 962 } 963#ifdef CPU_CNMIPS 964 else if (cop == 2) { 965 addr = trapframe->pc; 966 if ((td->td_md.md_flags & MDTD_COP2USED) && 967 (td->td_md.md_cop2owner == COP2_OWNER_KERNEL)) { 968 if (td->td_md.md_cop2) 969 octeon_cop2_save(td->td_md.md_cop2); 970 else 971 panic("COP2 was used in kernel mode but md_cop2 is NULL"); 972 } 973 974 if (td->td_md.md_ucop2 == NULL) { 975 td->td_md.md_ucop2 = octeon_cop2_alloc_ctx(); 976 if (td->td_md.md_ucop2 == NULL) 977 panic("Failed to allocate userland COP2 context"); 978 memset(td->td_md.md_ucop2, 0, sizeof(*td->td_md.md_ucop2)); 979 } 980 981 octeon_cop2_restore(td->td_md.md_ucop2); 982 983 td->td_frame->sr |= MIPS_SR_COP_2_BIT; 984 td->td_md.md_flags |= MDTD_COP2USED; 985 td->td_md.md_cop2owner = COP2_OWNER_USERLAND; 986 goto out; 987 } 988#endif 989 else { 990 log_illegal_instruction("COPn_UNUSABLE", trapframe); 991 i = SIGILL; /* only FPU instructions allowed */ 992 break; 993 } 994 995 case T_FPE: 996#if !defined(SMP) && (defined(DDB) || defined(DEBUG)) 997 trapDump("fpintr"); 998#else 999 printf("FPU Trap: PC %#jx CR %x SR %x\n", 1000 (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr); 1001 goto err; 1002#endif 1003 1004 case T_FPE + T_USER: 1005 if (!emulate_fp) { 1006 i = SIGILL; 1007 addr = trapframe->pc; 1008 break; 1009 } 1010 MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc); 1011 goto out; 1012 1013 case T_OVFLOW + T_USER: 1014 i = SIGFPE; 1015 addr = trapframe->pc; 1016 break; 1017 1018 case T_ADDR_ERR_LD: /* misaligned access */ 1019 case T_ADDR_ERR_ST: /* misaligned access */ 1020#ifdef TRAP_DEBUG 1021 if (trap_debug) { 1022 printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type, 1023 (intmax_t)trapframe->badvaddr); 1024 } 1025#endif 1026 /* Only allow emulation on a user address */ 1027 if (allow_unaligned_acc && 1028 ((vm_offset_t)trapframe->badvaddr < VM_MAXUSER_ADDRESS)) { 1029 int mode; 1030 1031 if (type == T_ADDR_ERR_LD) 1032 mode = VM_PROT_READ; 1033 else 1034 mode = VM_PROT_WRITE; 1035 1036 access_type = emulate_unaligned_access(trapframe, mode); 1037 if (access_type != 0) 1038 return (trapframe->pc); 1039 } 1040 /* FALLTHROUGH */ 1041 1042 case T_BUS_ERR_LD_ST: /* BERR asserted to cpu */ 1043 if (td->td_pcb->pcb_onfault != NULL) { 1044 pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; 1045 td->td_pcb->pcb_onfault = NULL; 1046 return (pc); 1047 } 1048 1049 /* FALLTHROUGH */ 1050 1051 default: 1052err: 1053 1054#if !defined(SMP) && defined(DEBUG) 1055 stacktrace(!usermode ? trapframe : td->td_frame); 1056 trapDump("trap"); 1057#endif 1058#ifdef SMP 1059 printf("cpu:%d-", PCPU_GET(cpuid)); 1060#endif 1061 printf("Trap cause = %d (%s - ", type, 1062 trap_type[type & (~T_USER)]); 1063 1064 if (type & T_USER) 1065 printf("user mode)\n"); 1066 else 1067 printf("kernel mode)\n"); 1068 1069#ifdef TRAP_DEBUG 1070 if (trap_debug) 1071 printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n", 1072 (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra, 1073 (intmax_t)trapframe->sr); 1074#endif 1075 1076#ifdef KDB 1077 if (debugger_on_panic || kdb_active) { 1078 kdb_trap(type, 0, trapframe); 1079 } 1080#endif 1081 panic("trap"); 1082 } 1083 td->td_frame->pc = trapframe->pc; 1084 td->td_frame->cause = trapframe->cause; 1085 td->td_frame->badvaddr = trapframe->badvaddr; 1086 ksiginfo_init_trap(&ksi); 1087 ksi.ksi_signo = i; 1088 ksi.ksi_code = ucode; 1089 ksi.ksi_addr = (void *)addr; 1090 ksi.ksi_trapno = type; 1091 trapsignal(td, &ksi); 1092out: 1093 1094 /* 1095 * Note: we should only get here if returning to user mode. 1096 */ 1097 userret(td, trapframe); 1098 return (trapframe->pc); 1099} 1100 1101#if !defined(SMP) && (defined(DDB) || defined(DEBUG)) 1102void 1103trapDump(char *msg) 1104{ 1105 register_t s; 1106 int i; 1107 1108 s = intr_disable(); 1109 printf("trapDump(%s)\n", msg); 1110 for (i = 0; i < TRAPSIZE; i++) { 1111 if (trp == trapdebug) { 1112 trp = &trapdebug[TRAPSIZE - 1]; 1113 } else { 1114 trp--; 1115 } 1116 1117 if (trp->cause == 0) 1118 break; 1119 1120 printf("%s: ADR %jx PC %jx CR %jx SR %jx\n", 1121 trap_type[(trp->cause & MIPS_CR_EXC_CODE) >> 1122 MIPS_CR_EXC_CODE_SHIFT], 1123 (intmax_t)trp->vadr, (intmax_t)trp->pc, 1124 (intmax_t)trp->cause, (intmax_t)trp->status); 1125 1126 printf(" RA %jx SP %jx code %d\n", (intmax_t)trp->ra, 1127 (intmax_t)trp->sp, (int)trp->code); 1128 } 1129 intr_restore(s); 1130} 1131#endif 1132 1133 1134/* 1135 * Return the resulting PC as if the branch was executed. 1136 */ 1137uintptr_t 1138MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, 1139 uintptr_t instptr) 1140{ 1141 InstFmt inst; 1142 register_t *regsPtr = (register_t *) framePtr; 1143 uintptr_t retAddr = 0; 1144 int condition; 1145 1146#define GetBranchDest(InstPtr, inst) \ 1147 (InstPtr + 4 + ((short)inst.IType.imm << 2)) 1148 1149 1150 if (instptr) { 1151 if (instptr < MIPS_KSEG0_START) 1152 inst.word = fuword32((void *)instptr); 1153 else 1154 inst = *(InstFmt *) instptr; 1155 } else { 1156 if ((vm_offset_t)instPC < MIPS_KSEG0_START) 1157 inst.word = fuword32((void *)instPC); 1158 else 1159 inst = *(InstFmt *) instPC; 1160 } 1161 1162 switch ((int)inst.JType.op) { 1163 case OP_SPECIAL: 1164 switch ((int)inst.RType.func) { 1165 case OP_JR: 1166 case OP_JALR: 1167 retAddr = regsPtr[inst.RType.rs]; 1168 break; 1169 1170 default: 1171 retAddr = instPC + 4; 1172 break; 1173 } 1174 break; 1175 1176 case OP_BCOND: 1177 switch ((int)inst.IType.rt) { 1178 case OP_BLTZ: 1179 case OP_BLTZL: 1180 case OP_BLTZAL: 1181 case OP_BLTZALL: 1182 if ((int)(regsPtr[inst.RType.rs]) < 0) 1183 retAddr = GetBranchDest(instPC, inst); 1184 else 1185 retAddr = instPC + 8; 1186 break; 1187 1188 case OP_BGEZ: 1189 case OP_BGEZL: 1190 case OP_BGEZAL: 1191 case OP_BGEZALL: 1192 if ((int)(regsPtr[inst.RType.rs]) >= 0) 1193 retAddr = GetBranchDest(instPC, inst); 1194 else 1195 retAddr = instPC + 8; 1196 break; 1197 1198 case OP_TGEI: 1199 case OP_TGEIU: 1200 case OP_TLTI: 1201 case OP_TLTIU: 1202 case OP_TEQI: 1203 case OP_TNEI: 1204 retAddr = instPC + 4; /* Like syscall... */ 1205 break; 1206 1207 default: 1208 panic("MipsEmulateBranch: Bad branch cond"); 1209 } 1210 break; 1211 1212 case OP_J: 1213 case OP_JAL: 1214 retAddr = (inst.JType.target << 2) | 1215 ((unsigned)(instPC + 4) & 0xF0000000); 1216 break; 1217 1218 case OP_BEQ: 1219 case OP_BEQL: 1220 if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt]) 1221 retAddr = GetBranchDest(instPC, inst); 1222 else 1223 retAddr = instPC + 8; 1224 break; 1225 1226 case OP_BNE: 1227 case OP_BNEL: 1228 if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt]) 1229 retAddr = GetBranchDest(instPC, inst); 1230 else 1231 retAddr = instPC + 8; 1232 break; 1233 1234 case OP_BLEZ: 1235 case OP_BLEZL: 1236 if ((int)(regsPtr[inst.RType.rs]) <= 0) 1237 retAddr = GetBranchDest(instPC, inst); 1238 else 1239 retAddr = instPC + 8; 1240 break; 1241 1242 case OP_BGTZ: 1243 case OP_BGTZL: 1244 if ((int)(regsPtr[inst.RType.rs]) > 0) 1245 retAddr = GetBranchDest(instPC, inst); 1246 else 1247 retAddr = instPC + 8; 1248 break; 1249 1250 case OP_COP1: 1251 switch (inst.RType.rs) { 1252 case OP_BCx: 1253 case OP_BCy: 1254 if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE) 1255 condition = fpcCSR & MIPS_FPU_COND_BIT; 1256 else 1257 condition = !(fpcCSR & MIPS_FPU_COND_BIT); 1258 if (condition) 1259 retAddr = GetBranchDest(instPC, inst); 1260 else 1261 retAddr = instPC + 8; 1262 break; 1263 1264 default: 1265 retAddr = instPC + 4; 1266 } 1267 break; 1268 1269 default: 1270 retAddr = instPC + 4; 1271 } 1272 return (retAddr); 1273} 1274 1275 1276#if defined(DDB) || defined(DEBUG) 1277/* 1278 * Print a stack backtrace. 1279 */ 1280void 1281stacktrace(struct trapframe *regs) 1282{ 1283 stacktrace_subr(regs->pc, regs->sp, regs->ra, printf); 1284} 1285#endif 1286 1287static void 1288log_frame_dump(struct trapframe *frame) 1289{ 1290 log(LOG_ERR, "Trapframe Register Dump:\n"); 1291 log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n", 1292 (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1); 1293 1294 log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n", 1295 (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3); 1296 1297 log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n", 1298 (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3); 1299 1300 log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n", 1301 (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7); 1302 1303 log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n", 1304 (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1); 1305 1306 log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n", 1307 (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5); 1308 1309 log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n", 1310 (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1); 1311 1312 log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n", 1313 (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra); 1314 1315 log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n", 1316 (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr); 1317 1318#ifdef IC_REG 1319 log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n", 1320 (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic); 1321#else 1322 log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n", 1323 (intmax_t)frame->cause, (intmax_t)frame->pc); 1324#endif 1325} 1326 1327#ifdef TRAP_DEBUG 1328static void 1329trap_frame_dump(struct trapframe *frame) 1330{ 1331 printf("Trapframe Register Dump:\n"); 1332 printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n", 1333 (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1); 1334 1335 printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n", 1336 (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3); 1337 1338 printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n", 1339 (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3); 1340 1341 printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n", 1342 (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7); 1343 1344 printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n", 1345 (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1); 1346 1347 printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n", 1348 (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5); 1349 1350 printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n", 1351 (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1); 1352 1353 printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n", 1354 (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra); 1355 1356 printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n", 1357 (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr); 1358 1359#ifdef IC_REG 1360 printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n", 1361 (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic); 1362#else 1363 printf("\tcause: %#jx\tpc: %#jx\n", 1364 (intmax_t)frame->cause, (intmax_t)frame->pc); 1365#endif 1366} 1367 1368#endif 1369 1370 1371static void 1372get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp) 1373{ 1374 pt_entry_t *ptep; 1375 pd_entry_t *pdep; 1376 struct proc *p = curproc; 1377 1378 pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)])); 1379 if (*pdep) 1380 ptep = pmap_pte(&p->p_vmspace->vm_pmap, va); 1381 else 1382 ptep = (pt_entry_t *)0; 1383 1384 *pdepp = pdep; 1385 *ptepp = ptep; 1386} 1387 1388static void 1389log_illegal_instruction(const char *msg, struct trapframe *frame) 1390{ 1391 pt_entry_t *ptep; 1392 pd_entry_t *pdep; 1393 unsigned int *addr; 1394 struct thread *td; 1395 struct proc *p; 1396 register_t pc; 1397 1398 td = curthread; 1399 p = td->td_proc; 1400 1401#ifdef SMP 1402 printf("cpuid = %d\n", PCPU_GET(cpuid)); 1403#endif 1404 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); 1405 log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n", 1406 msg, p->p_pid, (long)td->td_tid, p->p_comm, 1407 p->p_ucred ? p->p_ucred->cr_uid : -1, 1408 (intmax_t)pc, 1409 (intmax_t)frame->ra); 1410 1411 /* log registers in trap frame */ 1412 log_frame_dump(frame); 1413 1414 get_mapping_info((vm_offset_t)pc, &pdep, &ptep); 1415 1416 /* 1417 * Dump a few words around faulting instruction, if the addres is 1418 * valid. 1419 */ 1420 if (!(pc & 3) && 1421 useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { 1422 /* dump page table entry for faulting instruction */ 1423 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n", 1424 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1425 1426 addr = (unsigned int *)(intptr_t)pc; 1427 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n", 1428 addr); 1429 log(LOG_ERR, "%08x %08x %08x %08x\n", 1430 addr[0], addr[1], addr[2], addr[3]); 1431 } else { 1432 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n", 1433 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1434 } 1435} 1436 1437static void 1438log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) 1439{ 1440 pt_entry_t *ptep; 1441 pd_entry_t *pdep; 1442 unsigned int *addr; 1443 struct thread *td; 1444 struct proc *p; 1445 char *read_or_write; 1446 register_t pc; 1447 1448 trap_type &= ~T_USER; 1449 1450 td = curthread; 1451 p = td->td_proc; 1452 1453#ifdef SMP 1454 printf("cpuid = %d\n", PCPU_GET(cpuid)); 1455#endif 1456 switch (trap_type) { 1457 case T_TLB_ST_MISS: 1458 case T_ADDR_ERR_ST: 1459 read_or_write = "write"; 1460 break; 1461 case T_TLB_LD_MISS: 1462 case T_ADDR_ERR_LD: 1463 case T_BUS_ERR_IFETCH: 1464 read_or_write = "read"; 1465 break; 1466 default: 1467 read_or_write = "unknown"; 1468 } 1469 1470 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); 1471 log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault " 1472 "(type %#x) at %#jx\n", 1473 msg, p->p_pid, (long)td->td_tid, p->p_comm, 1474 p->p_ucred ? p->p_ucred->cr_uid : -1, 1475 (intmax_t)pc, 1476 read_or_write, 1477 trap_type, 1478 (intmax_t)frame->badvaddr); 1479 1480 /* log registers in trap frame */ 1481 log_frame_dump(frame); 1482 1483 get_mapping_info((vm_offset_t)pc, &pdep, &ptep); 1484 1485 /* 1486 * Dump a few words around faulting instruction, if the addres is 1487 * valid. 1488 */ 1489 if (!(pc & 3) && (pc != frame->badvaddr) && 1490 (trap_type != T_BUS_ERR_IFETCH) && 1491 useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { 1492 /* dump page table entry for faulting instruction */ 1493 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n", 1494 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1495 1496 addr = (unsigned int *)(intptr_t)pc; 1497 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n", 1498 addr); 1499 log(LOG_ERR, "%08x %08x %08x %08x\n", 1500 addr[0], addr[1], addr[2], addr[3]); 1501 } else { 1502 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n", 1503 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1504 } 1505 1506 get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep); 1507 log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n", 1508 (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1509} 1510 1511 1512/* 1513 * Unaligned load/store emulation 1514 */ 1515static int 1516mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc) 1517{ 1518 register_t *reg = (register_t *) frame; 1519 u_int32_t inst = *((u_int32_t *)(intptr_t)pc); 1520 register_t value_msb, value; 1521 unsigned size; 1522 1523 /* 1524 * ADDR_ERR faults have higher priority than TLB 1525 * Miss faults. Therefore, it is necessary to 1526 * verify that the faulting address is a valid 1527 * virtual address within the process' address space 1528 * before trying to emulate the unaligned access. 1529 */ 1530 switch (MIPS_INST_OPCODE(inst)) { 1531 case OP_LHU: case OP_LH: 1532 case OP_SH: 1533 size = 2; 1534 break; 1535 case OP_LWU: case OP_LW: 1536 case OP_SW: 1537 size = 4; 1538 break; 1539 case OP_LD: 1540 case OP_SD: 1541 size = 8; 1542 break; 1543 default: 1544 printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst)); 1545 return (0); 1546 } 1547 1548 if (!useracc((void *)((vm_offset_t)addr & ~(size - 1)), size * 2, mode)) 1549 return (0); 1550 1551 /* 1552 * XXX 1553 * Handle LL/SC LLD/SCD. 1554 */ 1555 switch (MIPS_INST_OPCODE(inst)) { 1556 case OP_LHU: 1557 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1558 lbu_macro(value_msb, addr); 1559 addr += 1; 1560 lbu_macro(value, addr); 1561 value |= value_msb << 8; 1562 reg[MIPS_INST_RT(inst)] = value; 1563 return (MIPS_LHU_ACCESS); 1564 1565 case OP_LH: 1566 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1567 lb_macro(value_msb, addr); 1568 addr += 1; 1569 lbu_macro(value, addr); 1570 value |= value_msb << 8; 1571 reg[MIPS_INST_RT(inst)] = value; 1572 return (MIPS_LH_ACCESS); 1573 1574 case OP_LWU: 1575 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1576 lwl_macro(value, addr); 1577 addr += 3; 1578 lwr_macro(value, addr); 1579 value &= 0xffffffff; 1580 reg[MIPS_INST_RT(inst)] = value; 1581 return (MIPS_LWU_ACCESS); 1582 1583 case OP_LW: 1584 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1585 lwl_macro(value, addr); 1586 addr += 3; 1587 lwr_macro(value, addr); 1588 reg[MIPS_INST_RT(inst)] = value; 1589 return (MIPS_LW_ACCESS); 1590 1591#if defined(__mips_n32) || defined(__mips_n64) 1592 case OP_LD: 1593 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1594 ldl_macro(value, addr); 1595 addr += 7; 1596 ldr_macro(value, addr); 1597 reg[MIPS_INST_RT(inst)] = value; 1598 return (MIPS_LD_ACCESS); 1599#endif 1600 1601 case OP_SH: 1602 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction.")); 1603 value = reg[MIPS_INST_RT(inst)]; 1604 value_msb = value >> 8; 1605 sb_macro(value_msb, addr); 1606 addr += 1; 1607 sb_macro(value, addr); 1608 return (MIPS_SH_ACCESS); 1609 1610 case OP_SW: 1611 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction.")); 1612 value = reg[MIPS_INST_RT(inst)]; 1613 swl_macro(value, addr); 1614 addr += 3; 1615 swr_macro(value, addr); 1616 return (MIPS_SW_ACCESS); 1617 1618#if defined(__mips_n32) || defined(__mips_n64) 1619 case OP_SD: 1620 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction.")); 1621 value = reg[MIPS_INST_RT(inst)]; 1622 sdl_macro(value, addr); 1623 addr += 7; 1624 sdr_macro(value, addr); 1625 return (MIPS_SD_ACCESS); 1626#endif 1627 } 1628 panic("%s: should not be reached.", __func__); 1629} 1630 1631 1632static int 1633emulate_unaligned_access(struct trapframe *frame, int mode) 1634{ 1635 register_t pc; 1636 int access_type = 0; 1637 1638 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); 1639 1640 /* 1641 * Fall through if it's instruction fetch exception 1642 */ 1643 if (!((pc & 3) || (pc == frame->badvaddr))) { 1644 1645 /* 1646 * Handle unaligned load and store 1647 */ 1648 1649 /* 1650 * Return access type if the instruction was emulated. 1651 * Otherwise restore pc and fall through. 1652 */ 1653 access_type = mips_unaligned_load_store(frame, 1654 mode, frame->badvaddr, pc); 1655 1656 if (access_type) { 1657 if (DELAYBRANCH(frame->cause)) 1658 frame->pc = MipsEmulateBranch(frame, frame->pc, 1659 0, 0); 1660 else 1661 frame->pc += 4; 1662 1663 log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n", 1664 access_name[access_type - 1], (intmax_t)pc, 1665 (intmax_t)frame->badvaddr); 1666 } 1667 } 1668 return access_type; 1669} 1670