1/* $NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $ */ 2 3/*- 4 * Copyright 2004 Olivier Houchard 5 * Copyright 2003 Wasabi Systems, Inc. 6 * All rights reserved. 7 * 8 * Written by Steve C. Woodford for Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed for the NetBSD Project by 21 * Wasabi Systems, Inc. 22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38/*- 39 * Copyright (c) 1994-1997 Mark Brinicombe. 40 * Copyright (c) 1994 Brini. 41 * All rights reserved. 42 * 43 * This code is derived from software written for Brini by Mark Brinicombe 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * This product includes software developed by Brini. 56 * 4. The name of the company nor the name of the author may be used to 57 * endorse or promote products derived from this software without specific 58 * prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 61 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 62 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 63 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 64 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 65 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 66 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 * RiscBSD kernel project 73 * 74 * fault.c 75 * 76 * Fault handlers 77 * 78 * Created : 28/11/94 79 */ 80 81 82#include <sys/cdefs.h> 83__FBSDID("$FreeBSD: stable/10/sys/arm/arm/trap.c 335557 2018-06-22 11:16:17Z avg $"); 84 85#include <sys/param.h> 86#include <sys/systm.h> 87#include <sys/proc.h> 88#include <sys/lock.h> 89#include <sys/mutex.h> 90#include <sys/signalvar.h> 91 92#include <vm/vm.h> 93#include <vm/pmap.h> 94#include <vm/vm_kern.h> 95#include <vm/vm_map.h> 96#include <vm/vm_extern.h> 97 98#include <machine/acle-compat.h> 99#include <machine/cpu.h> 100#include <machine/frame.h> 101#include <machine/machdep.h> 102#include <machine/pcb.h> 103#include <machine/vmparam.h> 104 105#ifdef KDB 106#include <sys/kdb.h> 107#endif 108 109extern char fusubailout[]; 110 111#ifdef DEBUG 112int last_fault_code; /* For the benefit of pmap_fault_fixup() */ 113#endif 114 115struct ksig { 116 int signb; 117 u_long code; 118}; 119struct data_abort { 120 int (*func)(struct trapframe *, u_int, u_int, struct thread *, 121 struct ksig *); 122 const char *desc; 123}; 124 125static int dab_fatal(struct trapframe *, u_int, u_int, struct thread *, 126 struct ksig *); 127static int dab_align(struct trapframe *, u_int, u_int, struct thread *, 128 struct ksig *); 129static int dab_buserr(struct trapframe *, u_int, u_int, struct thread *, 130 struct ksig *); 131static void prefetch_abort_handler(struct trapframe *); 132 133static const struct data_abort data_aborts[] = { 134 {dab_fatal, "Vector Exception"}, 135 {dab_align, "Alignment Fault 1"}, 136 {dab_fatal, "Terminal Exception"}, 137 {dab_align, "Alignment Fault 3"}, 138 {dab_buserr, "External Linefetch Abort (S)"}, 139 {NULL, "Translation Fault (S)"}, 140#if (ARM_MMU_V6 + ARM_MMU_V7) != 0 141 {NULL, "Translation Flag Fault"}, 142#else 143 {dab_buserr, "External Linefetch Abort (P)"}, 144#endif 145 {NULL, "Translation Fault (P)"}, 146 {dab_buserr, "External Non-Linefetch Abort (S)"}, 147 {NULL, "Domain Fault (S)"}, 148 {dab_buserr, "External Non-Linefetch Abort (P)"}, 149 {NULL, "Domain Fault (P)"}, 150 {dab_buserr, "External Translation Abort (L1)"}, 151 {NULL, "Permission Fault (S)"}, 152 {dab_buserr, "External Translation Abort (L2)"}, 153 {NULL, "Permission Fault (P)"} 154}; 155 156/* Determine if a fault came from user mode */ 157#define TRAP_USERMODE(tf) ((tf->tf_spsr & PSR_MODE) == PSR_USR32_MODE) 158 159/* Determine if 'x' is a permission fault */ 160#define IS_PERMISSION_FAULT(x) \ 161 (((1 << ((x) & FAULT_TYPE_MASK)) & \ 162 ((1 << FAULT_PERM_P) | (1 << FAULT_PERM_S))) != 0) 163 164static __inline void 165call_trapsignal(struct thread *td, int sig, u_long code) 166{ 167 ksiginfo_t ksi; 168 169 ksiginfo_init_trap(&ksi); 170 ksi.ksi_signo = sig; 171 ksi.ksi_code = (int)code; 172 trapsignal(td, &ksi); 173} 174 175void 176abort_handler(struct trapframe *tf, int type) 177{ 178 struct vm_map *map; 179 struct pcb *pcb; 180 struct thread *td; 181 u_int user, far, fsr; 182 vm_prot_t ftype; 183 void *onfault; 184 vm_offset_t va; 185 int error = 0; 186 struct ksig ksig; 187 struct proc *p; 188 189 if (type == 1) 190 return (prefetch_abort_handler(tf)); 191 192 /* Grab FAR/FSR before enabling interrupts */ 193 far = cpu_faultaddress(); 194 fsr = cpu_faultstatus(); 195#if 0 196 printf("data abort: fault address=%p (from pc=%p lr=%p)\n", 197 (void*)far, (void*)tf->tf_pc, (void*)tf->tf_svc_lr); 198#endif 199 200 /* Update vmmeter statistics */ 201#if 0 202 vmexp.traps++; 203#endif 204 205 td = curthread; 206 p = td->td_proc; 207 208 PCPU_INC(cnt.v_trap); 209 /* Data abort came from user mode? */ 210 user = TRAP_USERMODE(tf); 211 212 if (user) { 213 td->td_pticks = 0; 214 td->td_frame = tf; 215 if (td->td_ucred != td->td_proc->p_ucred) 216 cred_update_thread(td); 217 218 } 219 /* Grab the current pcb */ 220 pcb = td->td_pcb; 221 /* Re-enable interrupts if they were enabled previously */ 222 if (td->td_md.md_spinlock_count == 0) { 223 if (__predict_true(tf->tf_spsr & PSR_I) == 0) 224 enable_interrupts(PSR_I); 225 if (__predict_true(tf->tf_spsr & PSR_F) == 0) 226 enable_interrupts(PSR_F); 227 } 228 229 230 /* Invoke the appropriate handler, if necessary */ 231 if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) { 232 if ((data_aborts[fsr & FAULT_TYPE_MASK].func)(tf, fsr, far, 233 td, &ksig)) { 234 goto do_trapsignal; 235 } 236 goto out; 237 } 238 239 /* 240 * At this point, we're dealing with one of the following data aborts: 241 * 242 * FAULT_TRANS_S - Translation -- Section 243 * FAULT_TRANS_P - Translation -- Page 244 * FAULT_DOMAIN_S - Domain -- Section 245 * FAULT_DOMAIN_P - Domain -- Page 246 * FAULT_PERM_S - Permission -- Section 247 * FAULT_PERM_P - Permission -- Page 248 * 249 * These are the main virtual memory-related faults signalled by 250 * the MMU. 251 */ 252 253 /* fusubailout is used by [fs]uswintr to avoid page faulting */ 254 if (__predict_false(pcb->pcb_onfault == fusubailout)) { 255 tf->tf_r0 = EFAULT; 256 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault; 257 return; 258 } 259 260 /* 261 * Make sure the Program Counter is sane. We could fall foul of 262 * someone executing Thumb code, in which case the PC might not 263 * be word-aligned. This would cause a kernel alignment fault 264 * further down if we have to decode the current instruction. 265 * XXX: It would be nice to be able to support Thumb at some point. 266 */ 267 if (__predict_false((tf->tf_pc & 3) != 0)) { 268 if (user) { 269 /* 270 * Give the user an illegal instruction signal. 271 */ 272 /* Deliver a SIGILL to the process */ 273 ksig.signb = SIGILL; 274 ksig.code = 0; 275 goto do_trapsignal; 276 } 277 278 /* 279 * The kernel never executes Thumb code. 280 */ 281 printf("\ndata_abort_fault: Misaligned Kernel-mode " 282 "Program Counter\n"); 283 dab_fatal(tf, fsr, far, td, &ksig); 284 } 285 286 va = trunc_page((vm_offset_t)far); 287 288 /* 289 * It is only a kernel address space fault iff: 290 * 1. user == 0 and 291 * 2. pcb_onfault not set or 292 * 3. pcb_onfault set and not LDRT/LDRBT/STRT/STRBT instruction. 293 */ 294 if (user == 0 && (va >= VM_MIN_KERNEL_ADDRESS || 295 (va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) && 296 __predict_true((pcb->pcb_onfault == NULL || 297 (ReadWord(tf->tf_pc) & 0x05200000) != 0x04200000))) { 298 map = kernel_map; 299 300 /* Was the fault due to the FPE/IPKDB ? */ 301 if (__predict_false((tf->tf_spsr & PSR_MODE)==PSR_UND32_MODE)) { 302 303 /* 304 * Force exit via userret() 305 * This is necessary as the FPE is an extension to 306 * userland that actually runs in a priveledged mode 307 * but uses USR mode permissions for its accesses. 308 */ 309 user = 1; 310 ksig.signb = SIGSEGV; 311 ksig.code = 0; 312 goto do_trapsignal; 313 } 314 } else { 315 map = &td->td_proc->p_vmspace->vm_map; 316 } 317 318 /* 319 * We need to know whether the page should be mapped as R or R/W. On 320 * armv6 and later the fault status register indicates whether the 321 * access was a read or write. Prior to armv6, we know that a 322 * permission fault can only be the result of a write to a read-only 323 * location, so we can deal with those quickly. Otherwise we need to 324 * disassemble the faulting instruction to determine if it was a write. 325 */ 326#if __ARM_ARCH >= 6 327 ftype = (fsr & FAULT_WNR) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ; 328#else 329 if (IS_PERMISSION_FAULT(fsr)) 330 ftype = VM_PROT_WRITE; 331 else { 332 u_int insn = ReadWord(tf->tf_pc); 333 334 if (((insn & 0x0c100000) == 0x04000000) || /* STR/STRB */ 335 ((insn & 0x0e1000b0) == 0x000000b0) || /* STRH/STRD */ 336 ((insn & 0x0a100000) == 0x08000000)) { /* STM/CDT */ 337 ftype = VM_PROT_WRITE; 338 } else { 339 if ((insn & 0x0fb00ff0) == 0x01000090) /* SWP */ 340 ftype = VM_PROT_READ | VM_PROT_WRITE; 341 else 342 ftype = VM_PROT_READ; 343 } 344 } 345#endif 346 347 /* 348 * See if the fault is as a result of ref/mod emulation, 349 * or domain mismatch. 350 */ 351#ifdef DEBUG 352 last_fault_code = fsr; 353#endif 354 if (pmap_fault_fixup(vmspace_pmap(td->td_proc->p_vmspace), va, ftype, 355 user)) { 356 goto out; 357 } 358 359 onfault = pcb->pcb_onfault; 360 pcb->pcb_onfault = NULL; 361 if (map != kernel_map) { 362 PROC_LOCK(p); 363 p->p_lock++; 364 PROC_UNLOCK(p); 365 } 366 error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); 367 pcb->pcb_onfault = onfault; 368 369 if (map != kernel_map) { 370 PROC_LOCK(p); 371 p->p_lock--; 372 PROC_UNLOCK(p); 373 } 374 if (__predict_true(error == 0)) 375 goto out; 376 if (user == 0) { 377 if (pcb->pcb_onfault) { 378 tf->tf_r0 = error; 379 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault; 380 return; 381 } 382 383 printf("\nvm_fault(%p, %x, %x, 0) -> %x\n", map, va, ftype, 384 error); 385 dab_fatal(tf, fsr, far, td, &ksig); 386 } 387 388 389 if (error == ENOMEM) { 390 printf("VM: pid %d (%s), uid %d killed: " 391 "out of swap\n", td->td_proc->p_pid, td->td_name, 392 (td->td_proc->p_ucred) ? 393 td->td_proc->p_ucred->cr_uid : -1); 394 ksig.signb = SIGKILL; 395 } else { 396 ksig.signb = SIGSEGV; 397 } 398 ksig.code = 0; 399do_trapsignal: 400 call_trapsignal(td, ksig.signb, ksig.code); 401out: 402 /* If returning to user mode, make sure to invoke userret() */ 403 if (user) 404 userret(td, tf); 405} 406 407/* 408 * dab_fatal() handles the following data aborts: 409 * 410 * FAULT_WRTBUF_0 - Vector Exception 411 * FAULT_WRTBUF_1 - Terminal Exception 412 * 413 * We should never see these on a properly functioning system. 414 * 415 * This function is also called by the other handlers if they 416 * detect a fatal problem. 417 * 418 * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort. 419 */ 420static int 421dab_fatal(struct trapframe *tf, u_int fsr, u_int far, struct thread *td, 422 struct ksig *ksig) 423{ 424 const char *mode; 425#ifdef KDB 426 bool handled; 427#endif 428 429#ifdef KDB 430 if (kdb_active) { 431 kdb_reenter(); 432 return (0); 433 } 434#endif 435 mode = TRAP_USERMODE(tf) ? "user" : "kernel"; 436 437 disable_interrupts(PSR_I|PSR_F); 438 if (td != NULL) { 439 printf("Fatal %s mode data abort: '%s'\n", mode, 440 data_aborts[fsr & FAULT_TYPE_MASK].desc); 441 printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr); 442 if ((fsr & FAULT_IMPRECISE) == 0) 443 printf("%08x, ", far); 444 else 445 printf("Invalid, "); 446 printf("spsr=%08x\n", tf->tf_spsr); 447 } else { 448 printf("Fatal %s mode prefetch abort at 0x%08x\n", 449 mode, tf->tf_pc); 450 printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr); 451 } 452 453 printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n", 454 tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3); 455 printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n", 456 tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7); 457 printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n", 458 tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11); 459 printf("r12=%08x, ", tf->tf_r12); 460 461 if (TRAP_USERMODE(tf)) 462 printf("usp=%08x, ulr=%08x", 463 tf->tf_usr_sp, tf->tf_usr_lr); 464 else 465 printf("ssp=%08x, slr=%08x", 466 tf->tf_svc_sp, tf->tf_svc_lr); 467 printf(", pc =%08x\n\n", tf->tf_pc); 468 469#ifdef KDB 470 if (debugger_on_panic) { 471 kdb_why = KDB_WHY_TRAP; 472 handled = kdb_trap(fsr, 0, tf); 473 kdb_why = KDB_WHY_UNSET; 474 if (handled) 475 return (0); 476 } 477#endif 478 panic("Fatal abort"); 479 /*NOTREACHED*/ 480} 481 482/* 483 * dab_align() handles the following data aborts: 484 * 485 * FAULT_ALIGN_0 - Alignment fault 486 * FAULT_ALIGN_1 - Alignment fault 487 * 488 * These faults are fatal if they happen in kernel mode. Otherwise, we 489 * deliver a bus error to the process. 490 */ 491static int 492dab_align(struct trapframe *tf, u_int fsr, u_int far, struct thread *td, 493 struct ksig *ksig) 494{ 495 496 /* Alignment faults are always fatal if they occur in kernel mode */ 497 if (!TRAP_USERMODE(tf)) { 498 if (!td || !td->td_pcb->pcb_onfault) 499 dab_fatal(tf, fsr, far, td, ksig); 500 tf->tf_r0 = EFAULT; 501 tf->tf_pc = (int)td->td_pcb->pcb_onfault; 502 return (0); 503 } 504 505 /* pcb_onfault *must* be NULL at this point */ 506 507 /* Deliver a bus error signal to the process */ 508 ksig->code = 0; 509 ksig->signb = SIGBUS; 510 td->td_frame = tf; 511 512 return (1); 513} 514 515/* 516 * dab_buserr() handles the following data aborts: 517 * 518 * FAULT_BUSERR_0 - External Abort on Linefetch -- Section 519 * FAULT_BUSERR_1 - External Abort on Linefetch -- Page 520 * FAULT_BUSERR_2 - External Abort on Non-linefetch -- Section 521 * FAULT_BUSERR_3 - External Abort on Non-linefetch -- Page 522 * FAULT_BUSTRNL1 - External abort on Translation -- Level 1 523 * FAULT_BUSTRNL2 - External abort on Translation -- Level 2 524 * 525 * If pcb_onfault is set, flag the fault and return to the handler. 526 * If the fault occurred in user mode, give the process a SIGBUS. 527 * 528 * Note: On XScale, FAULT_BUSERR_0, FAULT_BUSERR_1, and FAULT_BUSERR_2 529 * can be flagged as imprecise in the FSR. This causes a real headache 530 * since some of the machine state is lost. In this case, tf->tf_pc 531 * may not actually point to the offending instruction. In fact, if 532 * we've taken a double abort fault, it generally points somewhere near 533 * the top of "data_abort_entry" in exception.S. 534 * 535 * In all other cases, these data aborts are considered fatal. 536 */ 537static int 538dab_buserr(struct trapframe *tf, u_int fsr, u_int far, struct thread *td, 539 struct ksig *ksig) 540{ 541 struct pcb *pcb = td->td_pcb; 542 543#ifdef __XSCALE__ 544 if ((fsr & FAULT_IMPRECISE) != 0 && 545 (tf->tf_spsr & PSR_MODE) == PSR_ABT32_MODE) { 546 /* 547 * Oops, an imprecise, double abort fault. We've lost the 548 * r14_abt/spsr_abt values corresponding to the original 549 * abort, and the spsr saved in the trapframe indicates 550 * ABT mode. 551 */ 552 tf->tf_spsr &= ~PSR_MODE; 553 554 /* 555 * We use a simple heuristic to determine if the double abort 556 * happened as a result of a kernel or user mode access. 557 * If the current trapframe is at the top of the kernel stack, 558 * the fault _must_ have come from user mode. 559 */ 560 if (tf != ((struct trapframe *)pcb->pcb_regs.sf_sp) - 1) { 561 /* 562 * Kernel mode. We're either about to die a 563 * spectacular death, or pcb_onfault will come 564 * to our rescue. Either way, the current value 565 * of tf->tf_pc is irrelevant. 566 */ 567 tf->tf_spsr |= PSR_SVC32_MODE; 568 if (pcb->pcb_onfault == NULL) 569 printf("\nKernel mode double abort!\n"); 570 } else { 571 /* 572 * User mode. We've lost the program counter at the 573 * time of the fault (not that it was accurate anyway; 574 * it's not called an imprecise fault for nothing). 575 * About all we can do is copy r14_usr to tf_pc and 576 * hope for the best. The process is about to get a 577 * SIGBUS, so it's probably history anyway. 578 */ 579 tf->tf_spsr |= PSR_USR32_MODE; 580 tf->tf_pc = tf->tf_usr_lr; 581 } 582 } 583 584 /* FAR is invalid for imprecise exceptions */ 585 if ((fsr & FAULT_IMPRECISE) != 0) 586 far = 0; 587#endif /* __XSCALE__ */ 588 589 if (pcb->pcb_onfault) { 590 tf->tf_r0 = EFAULT; 591 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault; 592 return (0); 593 } 594 595 /* 596 * At this point, if the fault happened in kernel mode, we're toast 597 */ 598 if (!TRAP_USERMODE(tf)) 599 dab_fatal(tf, fsr, far, td, ksig); 600 601 /* Deliver a bus error signal to the process */ 602 ksig->signb = SIGBUS; 603 ksig->code = 0; 604 td->td_frame = tf; 605 606 return (1); 607} 608 609/* 610 * void prefetch_abort_handler(struct trapframe *tf) 611 * 612 * Abort handler called when instruction execution occurs at 613 * a non existent or restricted (access permissions) memory page. 614 * If the address is invalid and we were in SVC mode then panic as 615 * the kernel should never prefetch abort. 616 * If the address is invalid and the page is mapped then the user process 617 * does no have read permission so send it a signal. 618 * Otherwise fault the page in and try again. 619 */ 620static void 621prefetch_abort_handler(struct trapframe *tf) 622{ 623 struct thread *td; 624 struct proc * p; 625 struct vm_map *map; 626 vm_offset_t fault_pc, va; 627 int error = 0; 628 struct ksig ksig; 629 630 631#if 0 632 /* Update vmmeter statistics */ 633 uvmexp.traps++; 634#endif 635#if 0 636 printf("prefetch abort handler: %p %p\n", (void*)tf->tf_pc, 637 (void*)tf->tf_usr_lr); 638#endif 639 640 td = curthread; 641 p = td->td_proc; 642 PCPU_INC(cnt.v_trap); 643 644 if (TRAP_USERMODE(tf)) { 645 td->td_frame = tf; 646 if (td->td_ucred != td->td_proc->p_ucred) 647 cred_update_thread(td); 648 } 649 fault_pc = tf->tf_pc; 650 if (td->td_md.md_spinlock_count == 0) { 651 if (__predict_true(tf->tf_spsr & PSR_I) == 0) 652 enable_interrupts(PSR_I); 653 if (__predict_true(tf->tf_spsr & PSR_F) == 0) 654 enable_interrupts(PSR_F); 655 } 656 657 /* Prefetch aborts cannot happen in kernel mode */ 658 if (__predict_false(!TRAP_USERMODE(tf))) 659 dab_fatal(tf, 0, tf->tf_pc, NULL, &ksig); 660 td->td_pticks = 0; 661 662 663 /* Ok validate the address, can only execute in USER space */ 664 if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS || 665 (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) { 666 ksig.signb = SIGSEGV; 667 ksig.code = 0; 668 goto do_trapsignal; 669 } 670 671 map = &td->td_proc->p_vmspace->vm_map; 672 va = trunc_page(fault_pc); 673 674 /* 675 * See if the pmap can handle this fault on its own... 676 */ 677#ifdef DEBUG 678 last_fault_code = -1; 679#endif 680 if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ, 1)) 681 goto out; 682 683 if (map != kernel_map) { 684 PROC_LOCK(p); 685 p->p_lock++; 686 PROC_UNLOCK(p); 687 } 688 689 error = vm_fault(map, va, VM_PROT_READ | VM_PROT_EXECUTE, 690 VM_FAULT_NORMAL); 691 if (map != kernel_map) { 692 PROC_LOCK(p); 693 p->p_lock--; 694 PROC_UNLOCK(p); 695 } 696 697 if (__predict_true(error == 0)) 698 goto out; 699 700 if (error == ENOMEM) { 701 printf("VM: pid %d (%s), uid %d killed: " 702 "out of swap\n", td->td_proc->p_pid, td->td_name, 703 (td->td_proc->p_ucred) ? 704 td->td_proc->p_ucred->cr_uid : -1); 705 ksig.signb = SIGKILL; 706 } else { 707 ksig.signb = SIGSEGV; 708 } 709 ksig.code = 0; 710 711do_trapsignal: 712 call_trapsignal(td, ksig.signb, ksig.code); 713 714out: 715 userret(td, tf); 716 717} 718 719extern int badaddr_read_1(const uint8_t *, uint8_t *); 720extern int badaddr_read_2(const uint16_t *, uint16_t *); 721extern int badaddr_read_4(const uint32_t *, uint32_t *); 722/* 723 * Tentatively read an 8, 16, or 32-bit value from 'addr'. 724 * If the read succeeds, the value is written to 'rptr' and zero is returned. 725 * Else, return EFAULT. 726 */ 727int 728badaddr_read(void *addr, size_t size, void *rptr) 729{ 730 union { 731 uint8_t v1; 732 uint16_t v2; 733 uint32_t v4; 734 } u; 735 int rv; 736 737 cpu_drain_writebuf(); 738 739 /* Read from the test address. */ 740 switch (size) { 741 case sizeof(uint8_t): 742 rv = badaddr_read_1(addr, &u.v1); 743 if (rv == 0 && rptr) 744 *(uint8_t *) rptr = u.v1; 745 break; 746 747 case sizeof(uint16_t): 748 rv = badaddr_read_2(addr, &u.v2); 749 if (rv == 0 && rptr) 750 *(uint16_t *) rptr = u.v2; 751 break; 752 753 case sizeof(uint32_t): 754 rv = badaddr_read_4(addr, &u.v4); 755 if (rv == 0 && rptr) 756 *(uint32_t *) rptr = u.v4; 757 break; 758 759 default: 760 panic("badaddr: invalid size (%lu)", (u_long) size); 761 } 762 763 /* Return EFAULT if the address was invalid, else zero */ 764 return (rv); 765} 766