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