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