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