trap.c revision 239669
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 239669 2012-08-25 08:02:46Z rwatson $"); 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 mtx_assert(&Giant, MA_NOTOWNED); 1099 return (trapframe->pc); 1100} 1101 1102#if !defined(SMP) && (defined(DDB) || defined(DEBUG)) 1103void 1104trapDump(char *msg) 1105{ 1106 register_t s; 1107 int i; 1108 1109 s = intr_disable(); 1110 printf("trapDump(%s)\n", msg); 1111 for (i = 0; i < TRAPSIZE; i++) { 1112 if (trp == trapdebug) { 1113 trp = &trapdebug[TRAPSIZE - 1]; 1114 } else { 1115 trp--; 1116 } 1117 1118 if (trp->cause == 0) 1119 break; 1120 1121 printf("%s: ADR %jx PC %jx CR %jx SR %jx\n", 1122 trap_type[(trp->cause & MIPS_CR_EXC_CODE) >> 1123 MIPS_CR_EXC_CODE_SHIFT], 1124 (intmax_t)trp->vadr, (intmax_t)trp->pc, 1125 (intmax_t)trp->cause, (intmax_t)trp->status); 1126 1127 printf(" RA %jx SP %jx code %d\n", (intmax_t)trp->ra, 1128 (intmax_t)trp->sp, (int)trp->code); 1129 } 1130 intr_restore(s); 1131} 1132#endif 1133 1134 1135/* 1136 * Return the resulting PC as if the branch was executed. 1137 */ 1138uintptr_t 1139MipsEmulateBranch(struct trapframe *framePtr, uintptr_t instPC, int fpcCSR, 1140 uintptr_t instptr) 1141{ 1142 InstFmt inst; 1143 register_t *regsPtr = (register_t *) framePtr; 1144 uintptr_t retAddr = 0; 1145 int condition; 1146 1147#define GetBranchDest(InstPtr, inst) \ 1148 (InstPtr + 4 + ((short)inst.IType.imm << 2)) 1149 1150 1151 if (instptr) { 1152 if (instptr < MIPS_KSEG0_START) 1153 inst.word = fuword32((void *)instptr); 1154 else 1155 inst = *(InstFmt *) instptr; 1156 } else { 1157 if ((vm_offset_t)instPC < MIPS_KSEG0_START) 1158 inst.word = fuword32((void *)instPC); 1159 else 1160 inst = *(InstFmt *) instPC; 1161 } 1162 1163 switch ((int)inst.JType.op) { 1164 case OP_SPECIAL: 1165 switch ((int)inst.RType.func) { 1166 case OP_JR: 1167 case OP_JALR: 1168 retAddr = regsPtr[inst.RType.rs]; 1169 break; 1170 1171 default: 1172 retAddr = instPC + 4; 1173 break; 1174 } 1175 break; 1176 1177 case OP_BCOND: 1178 switch ((int)inst.IType.rt) { 1179 case OP_BLTZ: 1180 case OP_BLTZL: 1181 case OP_BLTZAL: 1182 case OP_BLTZALL: 1183 if ((int)(regsPtr[inst.RType.rs]) < 0) 1184 retAddr = GetBranchDest(instPC, inst); 1185 else 1186 retAddr = instPC + 8; 1187 break; 1188 1189 case OP_BGEZ: 1190 case OP_BGEZL: 1191 case OP_BGEZAL: 1192 case OP_BGEZALL: 1193 if ((int)(regsPtr[inst.RType.rs]) >= 0) 1194 retAddr = GetBranchDest(instPC, inst); 1195 else 1196 retAddr = instPC + 8; 1197 break; 1198 1199 case OP_TGEI: 1200 case OP_TGEIU: 1201 case OP_TLTI: 1202 case OP_TLTIU: 1203 case OP_TEQI: 1204 case OP_TNEI: 1205 retAddr = instPC + 4; /* Like syscall... */ 1206 break; 1207 1208 default: 1209 panic("MipsEmulateBranch: Bad branch cond"); 1210 } 1211 break; 1212 1213 case OP_J: 1214 case OP_JAL: 1215 retAddr = (inst.JType.target << 2) | 1216 ((unsigned)(instPC + 4) & 0xF0000000); 1217 break; 1218 1219 case OP_BEQ: 1220 case OP_BEQL: 1221 if (regsPtr[inst.RType.rs] == regsPtr[inst.RType.rt]) 1222 retAddr = GetBranchDest(instPC, inst); 1223 else 1224 retAddr = instPC + 8; 1225 break; 1226 1227 case OP_BNE: 1228 case OP_BNEL: 1229 if (regsPtr[inst.RType.rs] != regsPtr[inst.RType.rt]) 1230 retAddr = GetBranchDest(instPC, inst); 1231 else 1232 retAddr = instPC + 8; 1233 break; 1234 1235 case OP_BLEZ: 1236 case OP_BLEZL: 1237 if ((int)(regsPtr[inst.RType.rs]) <= 0) 1238 retAddr = GetBranchDest(instPC, inst); 1239 else 1240 retAddr = instPC + 8; 1241 break; 1242 1243 case OP_BGTZ: 1244 case OP_BGTZL: 1245 if ((int)(regsPtr[inst.RType.rs]) > 0) 1246 retAddr = GetBranchDest(instPC, inst); 1247 else 1248 retAddr = instPC + 8; 1249 break; 1250 1251 case OP_COP1: 1252 switch (inst.RType.rs) { 1253 case OP_BCx: 1254 case OP_BCy: 1255 if ((inst.RType.rt & COPz_BC_TF_MASK) == COPz_BC_TRUE) 1256 condition = fpcCSR & MIPS_FPU_COND_BIT; 1257 else 1258 condition = !(fpcCSR & MIPS_FPU_COND_BIT); 1259 if (condition) 1260 retAddr = GetBranchDest(instPC, inst); 1261 else 1262 retAddr = instPC + 8; 1263 break; 1264 1265 default: 1266 retAddr = instPC + 4; 1267 } 1268 break; 1269 1270 default: 1271 retAddr = instPC + 4; 1272 } 1273 return (retAddr); 1274} 1275 1276 1277#if defined(DDB) || defined(DEBUG) 1278/* 1279 * Print a stack backtrace. 1280 */ 1281void 1282stacktrace(struct trapframe *regs) 1283{ 1284 stacktrace_subr(regs->pc, regs->sp, regs->ra, printf); 1285} 1286#endif 1287 1288static void 1289log_frame_dump(struct trapframe *frame) 1290{ 1291 log(LOG_ERR, "Trapframe Register Dump:\n"); 1292 log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n", 1293 (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1); 1294 1295 log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n", 1296 (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3); 1297 1298 log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n", 1299 (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3); 1300 1301 log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n", 1302 (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7); 1303 1304 log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n", 1305 (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1); 1306 1307 log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n", 1308 (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5); 1309 1310 log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n", 1311 (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1); 1312 1313 log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n", 1314 (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra); 1315 1316 log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n", 1317 (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr); 1318 1319#ifdef IC_REG 1320 log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n", 1321 (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic); 1322#else 1323 log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n", 1324 (intmax_t)frame->cause, (intmax_t)frame->pc); 1325#endif 1326} 1327 1328#ifdef TRAP_DEBUG 1329static void 1330trap_frame_dump(struct trapframe *frame) 1331{ 1332 printf("Trapframe Register Dump:\n"); 1333 printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n", 1334 (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1); 1335 1336 printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n", 1337 (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3); 1338 1339 printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n", 1340 (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3); 1341 1342 printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n", 1343 (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7); 1344 1345 printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n", 1346 (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1); 1347 1348 printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n", 1349 (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5); 1350 1351 printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n", 1352 (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1); 1353 1354 printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n", 1355 (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra); 1356 1357 printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n", 1358 (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr); 1359 1360#ifdef IC_REG 1361 printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n", 1362 (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic); 1363#else 1364 printf("\tcause: %#jx\tpc: %#jx\n", 1365 (intmax_t)frame->cause, (intmax_t)frame->pc); 1366#endif 1367} 1368 1369#endif 1370 1371 1372static void 1373get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp) 1374{ 1375 pt_entry_t *ptep; 1376 pd_entry_t *pdep; 1377 struct proc *p = curproc; 1378 1379 pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)])); 1380 if (*pdep) 1381 ptep = pmap_pte(&p->p_vmspace->vm_pmap, va); 1382 else 1383 ptep = (pt_entry_t *)0; 1384 1385 *pdepp = pdep; 1386 *ptepp = ptep; 1387} 1388 1389static void 1390log_illegal_instruction(const char *msg, struct trapframe *frame) 1391{ 1392 pt_entry_t *ptep; 1393 pd_entry_t *pdep; 1394 unsigned int *addr; 1395 struct thread *td; 1396 struct proc *p; 1397 register_t pc; 1398 1399 td = curthread; 1400 p = td->td_proc; 1401 1402#ifdef SMP 1403 printf("cpuid = %d\n", PCPU_GET(cpuid)); 1404#endif 1405 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); 1406 log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx ra %#jx\n", 1407 msg, p->p_pid, (long)td->td_tid, p->p_comm, 1408 p->p_ucred ? p->p_ucred->cr_uid : -1, 1409 (intmax_t)pc, 1410 (intmax_t)frame->ra); 1411 1412 /* log registers in trap frame */ 1413 log_frame_dump(frame); 1414 1415 get_mapping_info((vm_offset_t)pc, &pdep, &ptep); 1416 1417 /* 1418 * Dump a few words around faulting instruction, if the addres is 1419 * valid. 1420 */ 1421 if (!(pc & 3) && 1422 useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { 1423 /* dump page table entry for faulting instruction */ 1424 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n", 1425 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1426 1427 addr = (unsigned int *)(intptr_t)pc; 1428 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n", 1429 addr); 1430 log(LOG_ERR, "%08x %08x %08x %08x\n", 1431 addr[0], addr[1], addr[2], addr[3]); 1432 } else { 1433 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n", 1434 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1435 } 1436} 1437 1438static void 1439log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) 1440{ 1441 pt_entry_t *ptep; 1442 pd_entry_t *pdep; 1443 unsigned int *addr; 1444 struct thread *td; 1445 struct proc *p; 1446 char *read_or_write; 1447 register_t pc; 1448 1449 trap_type &= ~T_USER; 1450 1451 td = curthread; 1452 p = td->td_proc; 1453 1454#ifdef SMP 1455 printf("cpuid = %d\n", PCPU_GET(cpuid)); 1456#endif 1457 switch (trap_type) { 1458 case T_TLB_ST_MISS: 1459 case T_ADDR_ERR_ST: 1460 read_or_write = "write"; 1461 break; 1462 case T_TLB_LD_MISS: 1463 case T_ADDR_ERR_LD: 1464 case T_BUS_ERR_IFETCH: 1465 read_or_write = "read"; 1466 break; 1467 default: 1468 read_or_write = "unknown"; 1469 } 1470 1471 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); 1472 log(LOG_ERR, "%s: pid %d tid %ld (%s), uid %d: pc %#jx got a %s fault " 1473 "(type %#x) at %#jx\n", 1474 msg, p->p_pid, (long)td->td_tid, p->p_comm, 1475 p->p_ucred ? p->p_ucred->cr_uid : -1, 1476 (intmax_t)pc, 1477 read_or_write, 1478 trap_type, 1479 (intmax_t)frame->badvaddr); 1480 1481 /* log registers in trap frame */ 1482 log_frame_dump(frame); 1483 1484 get_mapping_info((vm_offset_t)pc, &pdep, &ptep); 1485 1486 /* 1487 * Dump a few words around faulting instruction, if the addres is 1488 * valid. 1489 */ 1490 if (!(pc & 3) && (pc != frame->badvaddr) && 1491 (trap_type != T_BUS_ERR_IFETCH) && 1492 useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { 1493 /* dump page table entry for faulting instruction */ 1494 log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#jx\n", 1495 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1496 1497 addr = (unsigned int *)(intptr_t)pc; 1498 log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n", 1499 addr); 1500 log(LOG_ERR, "%08x %08x %08x %08x\n", 1501 addr[0], addr[1], addr[2], addr[3]); 1502 } else { 1503 log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#jx\n", 1504 (intmax_t)pc, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1505 } 1506 1507 get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep); 1508 log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#jx\n", 1509 (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, (uintmax_t)(ptep ? *ptep : 0)); 1510} 1511 1512 1513/* 1514 * Unaligned load/store emulation 1515 */ 1516static int 1517mips_unaligned_load_store(struct trapframe *frame, int mode, register_t addr, register_t pc) 1518{ 1519 register_t *reg = (register_t *) frame; 1520 u_int32_t inst = *((u_int32_t *)(intptr_t)pc); 1521 register_t value_msb, value; 1522 unsigned size; 1523 1524 /* 1525 * ADDR_ERR faults have higher priority than TLB 1526 * Miss faults. Therefore, it is necessary to 1527 * verify that the faulting address is a valid 1528 * virtual address within the process' address space 1529 * before trying to emulate the unaligned access. 1530 */ 1531 switch (MIPS_INST_OPCODE(inst)) { 1532 case OP_LHU: case OP_LH: 1533 case OP_SH: 1534 size = 2; 1535 break; 1536 case OP_LWU: case OP_LW: 1537 case OP_SW: 1538 size = 4; 1539 break; 1540 case OP_LD: 1541 case OP_SD: 1542 size = 8; 1543 break; 1544 default: 1545 printf("%s: unhandled opcode in address error: %#x\n", __func__, MIPS_INST_OPCODE(inst)); 1546 return (0); 1547 } 1548 1549 if (!useracc((void *)((vm_offset_t)addr & ~(size - 1)), size * 2, mode)) 1550 return (0); 1551 1552 /* 1553 * XXX 1554 * Handle LL/SC LLD/SCD. 1555 */ 1556 switch (MIPS_INST_OPCODE(inst)) { 1557 case OP_LHU: 1558 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1559 lbu_macro(value_msb, addr); 1560 addr += 1; 1561 lbu_macro(value, addr); 1562 value |= value_msb << 8; 1563 reg[MIPS_INST_RT(inst)] = value; 1564 return (MIPS_LHU_ACCESS); 1565 1566 case OP_LH: 1567 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1568 lb_macro(value_msb, addr); 1569 addr += 1; 1570 lbu_macro(value, addr); 1571 value |= value_msb << 8; 1572 reg[MIPS_INST_RT(inst)] = value; 1573 return (MIPS_LH_ACCESS); 1574 1575 case OP_LWU: 1576 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1577 lwl_macro(value, addr); 1578 addr += 3; 1579 lwr_macro(value, addr); 1580 value &= 0xffffffff; 1581 reg[MIPS_INST_RT(inst)] = value; 1582 return (MIPS_LWU_ACCESS); 1583 1584 case OP_LW: 1585 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1586 lwl_macro(value, addr); 1587 addr += 3; 1588 lwr_macro(value, addr); 1589 reg[MIPS_INST_RT(inst)] = value; 1590 return (MIPS_LW_ACCESS); 1591 1592#if defined(__mips_n32) || defined(__mips_n64) 1593 case OP_LD: 1594 KASSERT(mode == VM_PROT_READ, ("access mode must be read for load instruction.")); 1595 ldl_macro(value, addr); 1596 addr += 7; 1597 ldr_macro(value, addr); 1598 reg[MIPS_INST_RT(inst)] = value; 1599 return (MIPS_LD_ACCESS); 1600#endif 1601 1602 case OP_SH: 1603 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction.")); 1604 value = reg[MIPS_INST_RT(inst)]; 1605 value_msb = value >> 8; 1606 sb_macro(value_msb, addr); 1607 addr += 1; 1608 sb_macro(value, addr); 1609 return (MIPS_SH_ACCESS); 1610 1611 case OP_SW: 1612 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction.")); 1613 value = reg[MIPS_INST_RT(inst)]; 1614 swl_macro(value, addr); 1615 addr += 3; 1616 swr_macro(value, addr); 1617 return (MIPS_SW_ACCESS); 1618 1619#if defined(__mips_n32) || defined(__mips_n64) 1620 case OP_SD: 1621 KASSERT(mode == VM_PROT_WRITE, ("access mode must be write for store instruction.")); 1622 value = reg[MIPS_INST_RT(inst)]; 1623 sdl_macro(value, addr); 1624 addr += 7; 1625 sdr_macro(value, addr); 1626 return (MIPS_SD_ACCESS); 1627#endif 1628 } 1629 panic("%s: should not be reached.", __func__); 1630} 1631 1632 1633static int 1634emulate_unaligned_access(struct trapframe *frame, int mode) 1635{ 1636 register_t pc; 1637 int access_type = 0; 1638 1639 pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); 1640 1641 /* 1642 * Fall through if it's instruction fetch exception 1643 */ 1644 if (!((pc & 3) || (pc == frame->badvaddr))) { 1645 1646 /* 1647 * Handle unaligned load and store 1648 */ 1649 1650 /* 1651 * Return access type if the instruction was emulated. 1652 * Otherwise restore pc and fall through. 1653 */ 1654 access_type = mips_unaligned_load_store(frame, 1655 mode, frame->badvaddr, pc); 1656 1657 if (access_type) { 1658 if (DELAYBRANCH(frame->cause)) 1659 frame->pc = MipsEmulateBranch(frame, frame->pc, 1660 0, 0); 1661 else 1662 frame->pc += 4; 1663 1664 log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n", 1665 access_name[access_type - 1], (intmax_t)pc, 1666 (intmax_t)frame->badvaddr); 1667 } 1668 } 1669 return access_type; 1670} 1671