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