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