The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/trap.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 "opt_ktrace.h"
   83 
   84 #include <sys/cdefs.h>
   85 __FBSDID("$FreeBSD: releng/10.0/sys/arm/arm/trap.c 253142 2013-07-10 10:15:38Z ray $");
   86 
   87 #include <sys/param.h>
   88 #include <sys/systm.h>
   89 #include <sys/proc.h>
   90 #include <sys/kernel.h>
   91 #include <sys/lock.h>
   92 #include <sys/mutex.h>
   93 #include <sys/syscall.h>
   94 #include <sys/sysent.h>
   95 #include <sys/signalvar.h>
   96 #include <sys/ktr.h>
   97 #ifdef KTRACE
   98 #include <sys/uio.h>
   99 #include <sys/ktrace.h>
  100 #endif
  101 #include <sys/ptrace.h>
  102 #include <sys/pioctl.h>
  103 
  104 #include <vm/vm.h>
  105 #include <vm/pmap.h>
  106 #include <vm/vm_kern.h>
  107 #include <vm/vm_map.h>
  108 #include <vm/vm_extern.h>
  109 
  110 #include <machine/cpuconf.h>
  111 #include <machine/vmparam.h>
  112 #include <machine/frame.h>
  113 #include <machine/cpu.h>
  114 #include <machine/intr.h>
  115 #include <machine/pcb.h>
  116 #include <machine/proc.h>
  117 #include <machine/swi.h>
  118 
  119 #include <security/audit/audit.h>
  120 
  121 #ifdef KDB
  122 #include <sys/kdb.h>
  123 #endif
  124 
  125 
  126 void swi_handler(trapframe_t *);
  127 void undefinedinstruction(trapframe_t *);
  128 
  129 #include <machine/disassem.h>
  130 #include <machine/machdep.h>
  131 
  132 extern char fusubailout[];
  133 
  134 #ifdef DEBUG
  135 int last_fault_code;    /* For the benefit of pmap_fault_fixup() */
  136 #endif
  137 
  138 #if defined(CPU_ARM7TDMI)
  139 /* These CPUs may need data/prefetch abort fixups */
  140 #define CPU_ABORT_FIXUP_REQUIRED
  141 #endif
  142 
  143 struct ksig {
  144         int signb;
  145         u_long code;
  146 };
  147 struct data_abort {
  148         int (*func)(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
  149         const char *desc;
  150 };
  151 
  152 static int dab_fatal(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
  153 static int dab_align(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
  154 static int dab_buserr(trapframe_t *, u_int, u_int, struct thread *, struct ksig *);
  155 
  156 static const struct data_abort data_aborts[] = {
  157         {dab_fatal,     "Vector Exception"},
  158         {dab_align,     "Alignment Fault 1"},
  159         {dab_fatal,     "Terminal Exception"},
  160         {dab_align,     "Alignment Fault 3"},
  161         {dab_buserr,    "External Linefetch Abort (S)"},
  162         {NULL,          "Translation Fault (S)"},
  163 #if (ARM_MMU_V6 + ARM_MMU_V7) != 0
  164         {NULL,          "Translation Flag Fault"},
  165 #else
  166         {dab_buserr,    "External Linefetch Abort (P)"},
  167 #endif
  168         {NULL,          "Translation Fault (P)"},
  169         {dab_buserr,    "External Non-Linefetch Abort (S)"},
  170         {NULL,          "Domain Fault (S)"},
  171         {dab_buserr,    "External Non-Linefetch Abort (P)"},
  172         {NULL,          "Domain Fault (P)"},
  173         {dab_buserr,    "External Translation Abort (L1)"},
  174         {NULL,          "Permission Fault (S)"},
  175         {dab_buserr,    "External Translation Abort (L2)"},
  176         {NULL,          "Permission Fault (P)"}
  177 };
  178 
  179 /* Determine if a fault came from user mode */
  180 #define TRAP_USERMODE(tf)       ((tf->tf_spsr & PSR_MODE) == PSR_USR32_MODE)
  181 
  182 /* Determine if 'x' is a permission fault */
  183 #define IS_PERMISSION_FAULT(x)                                  \
  184         (((1 << ((x) & FAULT_TYPE_MASK)) &                      \
  185           ((1 << FAULT_PERM_P) | (1 << FAULT_PERM_S))) != 0)
  186 
  187 static __inline void
  188 call_trapsignal(struct thread *td, int sig, u_long code)
  189 {
  190         ksiginfo_t ksi;
  191 
  192         ksiginfo_init_trap(&ksi);
  193         ksi.ksi_signo = sig;
  194         ksi.ksi_code = (int)code;
  195         trapsignal(td, &ksi);
  196 }
  197 
  198 static __inline int
  199 data_abort_fixup(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
  200 {
  201 #ifdef CPU_ABORT_FIXUP_REQUIRED
  202         int error;
  203 
  204         /* Call the cpu specific data abort fixup routine */
  205         error = cpu_dataabt_fixup(tf);
  206         if (__predict_true(error != ABORT_FIXUP_FAILED))
  207                 return (error);
  208 
  209         /*
  210          * Oops, couldn't fix up the instruction
  211          */
  212         printf("data_abort_fixup: fixup for %s mode data abort failed.\n",
  213             TRAP_USERMODE(tf) ? "user" : "kernel");
  214         printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
  215             *((u_int *)tf->tf_pc));
  216         disassemble(tf->tf_pc);
  217 
  218         /* Die now if this happened in kernel mode */
  219         if (!TRAP_USERMODE(tf))
  220                 dab_fatal(tf, fsr, far, td, NULL, ksig);
  221 
  222         return (error);
  223 #else
  224         return (ABORT_FIXUP_OK);
  225 #endif /* CPU_ABORT_FIXUP_REQUIRED */
  226 }
  227 
  228 void
  229 data_abort_handler(trapframe_t *tf)
  230 {
  231         struct vm_map *map;
  232         struct pcb *pcb;
  233         struct thread *td;
  234         u_int user, far, fsr;
  235         vm_prot_t ftype;
  236         void *onfault;
  237         vm_offset_t va;
  238         int error = 0;
  239         struct ksig ksig;
  240         struct proc *p;
  241 
  242 
  243         /* Grab FAR/FSR before enabling interrupts */
  244         far = cpu_faultaddress();
  245         fsr = cpu_faultstatus();
  246 #if 0
  247         printf("data abort: fault address=%p (from pc=%p lr=%p)\n",
  248                (void*)far, (void*)tf->tf_pc, (void*)tf->tf_svc_lr);
  249 #endif
  250 
  251         /* Update vmmeter statistics */
  252 #if 0
  253         vmexp.traps++;
  254 #endif
  255 
  256         td = curthread;
  257         p = td->td_proc;
  258 
  259         PCPU_INC(cnt.v_trap);
  260         /* Data abort came from user mode? */
  261         user = TRAP_USERMODE(tf);
  262 
  263         if (user) {
  264                 td->td_pticks = 0;
  265                 td->td_frame = tf;
  266                 if (td->td_ucred != td->td_proc->p_ucred)
  267                         cred_update_thread(td);
  268 
  269         }
  270         /* Grab the current pcb */
  271         pcb = td->td_pcb;
  272         /* Re-enable interrupts if they were enabled previously */
  273         if (td->td_md.md_spinlock_count == 0) {
  274                 if (__predict_true(tf->tf_spsr & I32_bit) == 0)
  275                         enable_interrupts(I32_bit);
  276                 if (__predict_true(tf->tf_spsr & F32_bit) == 0)
  277                         enable_interrupts(F32_bit);
  278         }
  279 
  280 
  281         /* Invoke the appropriate handler, if necessary */
  282         if (__predict_false(data_aborts[fsr & FAULT_TYPE_MASK].func != NULL)) {
  283                 if ((data_aborts[fsr & FAULT_TYPE_MASK].func)(tf, fsr, far,
  284                     td, &ksig)) {
  285                         goto do_trapsignal;
  286                 }
  287                 goto out;
  288         }
  289 
  290         /*
  291          * At this point, we're dealing with one of the following data aborts:
  292          *
  293          *  FAULT_TRANS_S  - Translation -- Section
  294          *  FAULT_TRANS_P  - Translation -- Page
  295          *  FAULT_DOMAIN_S - Domain -- Section
  296          *  FAULT_DOMAIN_P - Domain -- Page
  297          *  FAULT_PERM_S   - Permission -- Section
  298          *  FAULT_PERM_P   - Permission -- Page
  299          *
  300          * These are the main virtual memory-related faults signalled by
  301          * the MMU.
  302          */
  303 
  304         /* fusubailout is used by [fs]uswintr to avoid page faulting */
  305         if (__predict_false(pcb->pcb_onfault == fusubailout)) {
  306                 tf->tf_r0 = EFAULT;
  307                 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
  308                 return;
  309         }
  310 
  311         /*
  312          * Make sure the Program Counter is sane. We could fall foul of
  313          * someone executing Thumb code, in which case the PC might not
  314          * be word-aligned. This would cause a kernel alignment fault
  315          * further down if we have to decode the current instruction.
  316          * XXX: It would be nice to be able to support Thumb at some point.
  317          */
  318         if (__predict_false((tf->tf_pc & 3) != 0)) {
  319                 if (user) {
  320                         /*
  321                          * Give the user an illegal instruction signal.
  322                          */
  323                         /* Deliver a SIGILL to the process */
  324                         ksig.signb = SIGILL;
  325                         ksig.code = 0;
  326                         goto do_trapsignal;
  327                 }
  328 
  329                 /*
  330                  * The kernel never executes Thumb code.
  331                  */
  332                 printf("\ndata_abort_fault: Misaligned Kernel-mode "
  333                     "Program Counter\n");
  334                 dab_fatal(tf, fsr, far, td, &ksig);
  335         }
  336 
  337         /* See if the cpu state needs to be fixed up */
  338         switch (data_abort_fixup(tf, fsr, far, td, &ksig)) {
  339         case ABORT_FIXUP_RETURN:
  340                 return;
  341         case ABORT_FIXUP_FAILED:
  342                 /* Deliver a SIGILL to the process */
  343                 ksig.signb = SIGILL;
  344                 ksig.code = 0;
  345                 goto do_trapsignal;
  346         default:
  347                 break;
  348         }
  349 
  350         va = trunc_page((vm_offset_t)far);
  351 
  352         /*
  353          * It is only a kernel address space fault iff:
  354          *      1. user == 0  and
  355          *      2. pcb_onfault not set or
  356          *      3. pcb_onfault set and not LDRT/LDRBT/STRT/STRBT instruction.
  357          */
  358         if (user == 0 && (va >= VM_MIN_KERNEL_ADDRESS ||
  359             (va < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW)) &&
  360             __predict_true((pcb->pcb_onfault == NULL ||
  361              (ReadWord(tf->tf_pc) & 0x05200000) != 0x04200000))) {
  362                 map = kernel_map;
  363 
  364                 /* Was the fault due to the FPE/IPKDB ? */
  365                 if (__predict_false((tf->tf_spsr & PSR_MODE)==PSR_UND32_MODE)) {
  366 
  367                         /*
  368                          * Force exit via userret()
  369                          * This is necessary as the FPE is an extension to
  370                          * userland that actually runs in a priveledged mode
  371                          * but uses USR mode permissions for its accesses.
  372                          */
  373                         user = 1;
  374                         ksig.signb = SIGSEGV;
  375                         ksig.code = 0;
  376                         goto do_trapsignal;
  377                 }
  378         } else {
  379                 map = &td->td_proc->p_vmspace->vm_map;
  380         }
  381 
  382         /*
  383          * We need to know whether the page should be mapped
  384          * as R or R/W. The MMU does not give us the info as
  385          * to whether the fault was caused by a read or a write.
  386          *
  387          * However, we know that a permission fault can only be
  388          * the result of a write to a read-only location, so
  389          * we can deal with those quickly.
  390          *
  391          * Otherwise we need to disassemble the instruction
  392          * responsible to determine if it was a write.
  393          */
  394         if (IS_PERMISSION_FAULT(fsr))
  395                 ftype = VM_PROT_WRITE;
  396         else {
  397                 u_int insn = ReadWord(tf->tf_pc);
  398 
  399                 if (((insn & 0x0c100000) == 0x04000000) ||      /* STR/STRB */
  400                     ((insn & 0x0e1000b0) == 0x000000b0) ||      /* STRH/STRD */
  401                     ((insn & 0x0a100000) == 0x08000000)) {      /* STM/CDT */
  402                         ftype = VM_PROT_WRITE;
  403                 } else {
  404                         if ((insn & 0x0fb00ff0) == 0x01000090)  /* SWP */
  405                                 ftype = VM_PROT_READ | VM_PROT_WRITE;
  406                         else
  407                                 ftype = VM_PROT_READ;
  408                 }
  409         }
  410 
  411         /*
  412          * See if the fault is as a result of ref/mod emulation,
  413          * or domain mismatch.
  414          */
  415 #ifdef DEBUG
  416         last_fault_code = fsr;
  417 #endif
  418         if (pmap_fault_fixup(vmspace_pmap(td->td_proc->p_vmspace), va, ftype,
  419             user)) {
  420                 goto out;
  421         }
  422 
  423         onfault = pcb->pcb_onfault;
  424         pcb->pcb_onfault = NULL;
  425         if (map != kernel_map) {
  426                 PROC_LOCK(p);
  427                 p->p_lock++;
  428                 PROC_UNLOCK(p);
  429         }
  430         error = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
  431         pcb->pcb_onfault = onfault;
  432 
  433         if (map != kernel_map) {
  434                 PROC_LOCK(p);
  435                 p->p_lock--;
  436                 PROC_UNLOCK(p);
  437         }
  438         if (__predict_true(error == 0))
  439                 goto out;
  440         if (user == 0) {
  441                 if (pcb->pcb_onfault) {
  442                         tf->tf_r0 = error;
  443                         tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
  444                         return;
  445                 }
  446 
  447                 printf("\nvm_fault(%p, %x, %x, 0) -> %x\n", map, va, ftype,
  448                     error);
  449                 dab_fatal(tf, fsr, far, td, &ksig);
  450         }
  451 
  452 
  453         if (error == ENOMEM) {
  454                 printf("VM: pid %d (%s), uid %d killed: "
  455                     "out of swap\n", td->td_proc->p_pid, td->td_name,
  456                     (td->td_proc->p_ucred) ?
  457                      td->td_proc->p_ucred->cr_uid : -1);
  458                 ksig.signb = SIGKILL;
  459         } else {
  460                 ksig.signb = SIGSEGV;
  461         }
  462         ksig.code = 0;
  463 do_trapsignal:
  464         call_trapsignal(td, ksig.signb, ksig.code);
  465 out:
  466         /* If returning to user mode, make sure to invoke userret() */
  467         if (user)
  468                 userret(td, tf);
  469 }
  470 
  471 /*
  472  * dab_fatal() handles the following data aborts:
  473  *
  474  *  FAULT_WRTBUF_0 - Vector Exception
  475  *  FAULT_WRTBUF_1 - Terminal Exception
  476  *
  477  * We should never see these on a properly functioning system.
  478  *
  479  * This function is also called by the other handlers if they
  480  * detect a fatal problem.
  481  *
  482  * Note: If 'l' is NULL, we assume we're dealing with a prefetch abort.
  483  */
  484 static int
  485 dab_fatal(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
  486 {
  487         const char *mode;
  488 
  489         mode = TRAP_USERMODE(tf) ? "user" : "kernel";
  490 
  491         disable_interrupts(I32_bit|F32_bit);
  492         if (td != NULL) {
  493                 printf("Fatal %s mode data abort: '%s'\n", mode,
  494                     data_aborts[fsr & FAULT_TYPE_MASK].desc);
  495                 printf("trapframe: %p\nFSR=%08x, FAR=", tf, fsr);
  496                 if ((fsr & FAULT_IMPRECISE) == 0)
  497                         printf("%08x, ", far);
  498                 else
  499                         printf("Invalid,  ");
  500                 printf("spsr=%08x\n", tf->tf_spsr);
  501         } else {
  502                 printf("Fatal %s mode prefetch abort at 0x%08x\n",
  503                     mode, tf->tf_pc);
  504                 printf("trapframe: %p, spsr=%08x\n", tf, tf->tf_spsr);
  505         }
  506 
  507         printf("r0 =%08x, r1 =%08x, r2 =%08x, r3 =%08x\n",
  508             tf->tf_r0, tf->tf_r1, tf->tf_r2, tf->tf_r3);
  509         printf("r4 =%08x, r5 =%08x, r6 =%08x, r7 =%08x\n",
  510             tf->tf_r4, tf->tf_r5, tf->tf_r6, tf->tf_r7);
  511         printf("r8 =%08x, r9 =%08x, r10=%08x, r11=%08x\n",
  512             tf->tf_r8, tf->tf_r9, tf->tf_r10, tf->tf_r11);
  513         printf("r12=%08x, ", tf->tf_r12);
  514 
  515         if (TRAP_USERMODE(tf))
  516                 printf("usp=%08x, ulr=%08x",
  517                     tf->tf_usr_sp, tf->tf_usr_lr);
  518         else
  519                 printf("ssp=%08x, slr=%08x",
  520                     tf->tf_svc_sp, tf->tf_svc_lr);
  521         printf(", pc =%08x\n\n", tf->tf_pc);
  522 
  523 #ifdef KDB
  524         if (debugger_on_panic || kdb_active)
  525                 kdb_trap(fsr, 0, tf);
  526 #endif
  527         panic("Fatal abort");
  528         /*NOTREACHED*/
  529 }
  530 
  531 /*
  532  * dab_align() handles the following data aborts:
  533  *
  534  *  FAULT_ALIGN_0 - Alignment fault
  535  *  FAULT_ALIGN_1 - Alignment fault
  536  *
  537  * These faults are fatal if they happen in kernel mode. Otherwise, we
  538  * deliver a bus error to the process.
  539  */
  540 static int
  541 dab_align(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
  542 {
  543 
  544         /* Alignment faults are always fatal if they occur in kernel mode */
  545         if (!TRAP_USERMODE(tf)) {
  546                 if (!td || !td->td_pcb->pcb_onfault)
  547                         dab_fatal(tf, fsr, far, td, ksig);
  548                 tf->tf_r0 = EFAULT;
  549                 tf->tf_pc = (int)td->td_pcb->pcb_onfault;
  550                 return (0);
  551         }
  552 
  553         /* pcb_onfault *must* be NULL at this point */
  554 
  555         /* See if the cpu state needs to be fixed up */
  556         (void) data_abort_fixup(tf, fsr, far, td, ksig);
  557 
  558         /* Deliver a bus error signal to the process */
  559         ksig->code = 0;
  560         ksig->signb = SIGBUS;
  561         td->td_frame = tf;
  562 
  563         return (1);
  564 }
  565 
  566 /*
  567  * dab_buserr() handles the following data aborts:
  568  *
  569  *  FAULT_BUSERR_0 - External Abort on Linefetch -- Section
  570  *  FAULT_BUSERR_1 - External Abort on Linefetch -- Page
  571  *  FAULT_BUSERR_2 - External Abort on Non-linefetch -- Section
  572  *  FAULT_BUSERR_3 - External Abort on Non-linefetch -- Page
  573  *  FAULT_BUSTRNL1 - External abort on Translation -- Level 1
  574  *  FAULT_BUSTRNL2 - External abort on Translation -- Level 2
  575  *
  576  * If pcb_onfault is set, flag the fault and return to the handler.
  577  * If the fault occurred in user mode, give the process a SIGBUS.
  578  *
  579  * Note: On XScale, FAULT_BUSERR_0, FAULT_BUSERR_1, and FAULT_BUSERR_2
  580  * can be flagged as imprecise in the FSR. This causes a real headache
  581  * since some of the machine state is lost. In this case, tf->tf_pc
  582  * may not actually point to the offending instruction. In fact, if
  583  * we've taken a double abort fault, it generally points somewhere near
  584  * the top of "data_abort_entry" in exception.S.
  585  *
  586  * In all other cases, these data aborts are considered fatal.
  587  */
  588 static int
  589 dab_buserr(trapframe_t *tf, u_int fsr, u_int far, struct thread *td, struct ksig *ksig)
  590 {
  591         struct pcb *pcb = td->td_pcb;
  592 
  593 #ifdef __XSCALE__
  594         if ((fsr & FAULT_IMPRECISE) != 0 &&
  595             (tf->tf_spsr & PSR_MODE) == PSR_ABT32_MODE) {
  596                 /*
  597                  * Oops, an imprecise, double abort fault. We've lost the
  598                  * r14_abt/spsr_abt values corresponding to the original
  599                  * abort, and the spsr saved in the trapframe indicates
  600                  * ABT mode.
  601                  */
  602                 tf->tf_spsr &= ~PSR_MODE;
  603 
  604                 /*
  605                  * We use a simple heuristic to determine if the double abort
  606                  * happened as a result of a kernel or user mode access.
  607                  * If the current trapframe is at the top of the kernel stack,
  608                  * the fault _must_ have come from user mode.
  609                  */
  610                 if (tf != ((trapframe_t *)pcb->un_32.pcb32_sp) - 1) {
  611                         /*
  612                          * Kernel mode. We're either about to die a
  613                          * spectacular death, or pcb_onfault will come
  614                          * to our rescue. Either way, the current value
  615                          * of tf->tf_pc is irrelevant.
  616                          */
  617                         tf->tf_spsr |= PSR_SVC32_MODE;
  618                         if (pcb->pcb_onfault == NULL)
  619                                 printf("\nKernel mode double abort!\n");
  620                 } else {
  621                         /*
  622                          * User mode. We've lost the program counter at the
  623                          * time of the fault (not that it was accurate anyway;
  624                          * it's not called an imprecise fault for nothing).
  625                          * About all we can do is copy r14_usr to tf_pc and
  626                          * hope for the best. The process is about to get a
  627                          * SIGBUS, so it's probably history anyway.
  628                          */
  629                         tf->tf_spsr |= PSR_USR32_MODE;
  630                         tf->tf_pc = tf->tf_usr_lr;
  631                 }
  632         }
  633 
  634         /* FAR is invalid for imprecise exceptions */
  635         if ((fsr & FAULT_IMPRECISE) != 0)
  636                 far = 0;
  637 #endif /* __XSCALE__ */
  638 
  639         if (pcb->pcb_onfault) {
  640                 tf->tf_r0 = EFAULT;
  641                 tf->tf_pc = (register_t)(intptr_t) pcb->pcb_onfault;
  642                 return (0);
  643         }
  644 
  645         /* See if the cpu state needs to be fixed up */
  646         (void) data_abort_fixup(tf, fsr, far, td, ksig);
  647 
  648         /*
  649          * At this point, if the fault happened in kernel mode, we're toast
  650          */
  651         if (!TRAP_USERMODE(tf))
  652                 dab_fatal(tf, fsr, far, td, ksig);
  653 
  654         /* Deliver a bus error signal to the process */
  655         ksig->signb = SIGBUS;
  656         ksig->code = 0;
  657         td->td_frame = tf;
  658 
  659         return (1);
  660 }
  661 
  662 static __inline int
  663 prefetch_abort_fixup(trapframe_t *tf, struct ksig *ksig)
  664 {
  665 #ifdef CPU_ABORT_FIXUP_REQUIRED
  666         int error;
  667 
  668         /* Call the cpu specific prefetch abort fixup routine */
  669         error = cpu_prefetchabt_fixup(tf);
  670         if (__predict_true(error != ABORT_FIXUP_FAILED))
  671                 return (error);
  672 
  673         /*
  674          * Oops, couldn't fix up the instruction
  675          */
  676         printf(
  677             "prefetch_abort_fixup: fixup for %s mode prefetch abort failed.\n",
  678             TRAP_USERMODE(tf) ? "user" : "kernel");
  679         printf("pc = 0x%08x, opcode 0x%08x, insn = ", tf->tf_pc,
  680             *((u_int *)tf->tf_pc));
  681         disassemble(tf->tf_pc);
  682 
  683         /* Die now if this happened in kernel mode */
  684         if (!TRAP_USERMODE(tf))
  685                 dab_fatal(tf, 0, tf->tf_pc, NULL, ksig);
  686 
  687         return (error);
  688 #else
  689         return (ABORT_FIXUP_OK);
  690 #endif /* CPU_ABORT_FIXUP_REQUIRED */
  691 }
  692 
  693 /*
  694  * void prefetch_abort_handler(trapframe_t *tf)
  695  *
  696  * Abort handler called when instruction execution occurs at
  697  * a non existent or restricted (access permissions) memory page.
  698  * If the address is invalid and we were in SVC mode then panic as
  699  * the kernel should never prefetch abort.
  700  * If the address is invalid and the page is mapped then the user process
  701  * does no have read permission so send it a signal.
  702  * Otherwise fault the page in and try again.
  703  */
  704 void
  705 prefetch_abort_handler(trapframe_t *tf)
  706 {
  707         struct thread *td;
  708         struct proc * p;
  709         struct vm_map *map;
  710         vm_offset_t fault_pc, va;
  711         int error = 0;
  712         struct ksig ksig;
  713 
  714 
  715 #if 0
  716         /* Update vmmeter statistics */
  717         uvmexp.traps++;
  718 #endif
  719 #if 0
  720         printf("prefetch abort handler: %p %p\n", (void*)tf->tf_pc,
  721             (void*)tf->tf_usr_lr);
  722 #endif
  723 
  724         td = curthread;
  725         p = td->td_proc;
  726         PCPU_INC(cnt.v_trap);
  727 
  728         if (TRAP_USERMODE(tf)) {
  729                 td->td_frame = tf;
  730                 if (td->td_ucred != td->td_proc->p_ucred)
  731                         cred_update_thread(td);
  732         }
  733         fault_pc = tf->tf_pc;
  734         if (td->td_md.md_spinlock_count == 0) {
  735                 if (__predict_true(tf->tf_spsr & I32_bit) == 0)
  736                         enable_interrupts(I32_bit);
  737                 if (__predict_true(tf->tf_spsr & F32_bit) == 0)
  738                         enable_interrupts(F32_bit);
  739         }
  740 
  741         /* See if the cpu state needs to be fixed up */
  742         switch (prefetch_abort_fixup(tf, &ksig)) {
  743         case ABORT_FIXUP_RETURN:
  744                 return;
  745         case ABORT_FIXUP_FAILED:
  746                 /* Deliver a SIGILL to the process */
  747                 ksig.signb = SIGILL;
  748                 ksig.code = 0;
  749                 td->td_frame = tf;
  750                 goto do_trapsignal;
  751         default:
  752                 break;
  753         }
  754 
  755         /* Prefetch aborts cannot happen in kernel mode */
  756         if (__predict_false(!TRAP_USERMODE(tf)))
  757                 dab_fatal(tf, 0, tf->tf_pc, NULL, &ksig);
  758         td->td_pticks = 0;
  759 
  760 
  761         /* Ok validate the address, can only execute in USER space */
  762         if (__predict_false(fault_pc >= VM_MAXUSER_ADDRESS ||
  763             (fault_pc < VM_MIN_ADDRESS && vector_page == ARM_VECTORS_LOW))) {
  764                 ksig.signb = SIGSEGV;
  765                 ksig.code = 0;
  766                 goto do_trapsignal;
  767         }
  768 
  769         map = &td->td_proc->p_vmspace->vm_map;
  770         va = trunc_page(fault_pc);
  771 
  772         /*
  773          * See if the pmap can handle this fault on its own...
  774          */
  775 #ifdef DEBUG
  776         last_fault_code = -1;
  777 #endif
  778         if (pmap_fault_fixup(map->pmap, va, VM_PROT_READ, 1))
  779                 goto out;
  780 
  781         if (map != kernel_map) {
  782                 PROC_LOCK(p);
  783                 p->p_lock++;
  784                 PROC_UNLOCK(p);
  785         }
  786 
  787         error = vm_fault(map, va, VM_PROT_READ | VM_PROT_EXECUTE,
  788             VM_FAULT_NORMAL);
  789         if (map != kernel_map) {
  790                 PROC_LOCK(p);
  791                 p->p_lock--;
  792                 PROC_UNLOCK(p);
  793         }
  794 
  795         if (__predict_true(error == 0))
  796                 goto out;
  797 
  798         if (error == ENOMEM) {
  799                 printf("VM: pid %d (%s), uid %d killed: "
  800                     "out of swap\n", td->td_proc->p_pid, td->td_name,
  801                     (td->td_proc->p_ucred) ?
  802                      td->td_proc->p_ucred->cr_uid : -1);
  803                 ksig.signb = SIGKILL;
  804         } else {
  805                 ksig.signb = SIGSEGV;
  806         }
  807         ksig.code = 0;
  808 
  809 do_trapsignal:
  810         call_trapsignal(td, ksig.signb, ksig.code);
  811 
  812 out:
  813         userret(td, tf);
  814 
  815 }
  816 
  817 extern int badaddr_read_1(const uint8_t *, uint8_t *);
  818 extern int badaddr_read_2(const uint16_t *, uint16_t *);
  819 extern int badaddr_read_4(const uint32_t *, uint32_t *);
  820 /*
  821  * Tentatively read an 8, 16, or 32-bit value from 'addr'.
  822  * If the read succeeds, the value is written to 'rptr' and zero is returned.
  823  * Else, return EFAULT.
  824  */
  825 int
  826 badaddr_read(void *addr, size_t size, void *rptr)
  827 {
  828         union {
  829                 uint8_t v1;
  830                 uint16_t v2;
  831                 uint32_t v4;
  832         } u;
  833         int rv;
  834 
  835         cpu_drain_writebuf();
  836 
  837         /* Read from the test address. */
  838         switch (size) {
  839         case sizeof(uint8_t):
  840                 rv = badaddr_read_1(addr, &u.v1);
  841                 if (rv == 0 && rptr)
  842                         *(uint8_t *) rptr = u.v1;
  843                 break;
  844 
  845         case sizeof(uint16_t):
  846                 rv = badaddr_read_2(addr, &u.v2);
  847                 if (rv == 0 && rptr)
  848                         *(uint16_t *) rptr = u.v2;
  849                 break;
  850 
  851         case sizeof(uint32_t):
  852                 rv = badaddr_read_4(addr, &u.v4);
  853                 if (rv == 0 && rptr)
  854                         *(uint32_t *) rptr = u.v4;
  855                 break;
  856 
  857         default:
  858                 panic("badaddr: invalid size (%lu)", (u_long) size);
  859         }
  860 
  861         /* Return EFAULT if the address was invalid, else zero */
  862         return (rv);
  863 }
  864 
  865 int
  866 cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
  867 {
  868         struct proc *p;
  869         register_t *ap;
  870         int error;
  871 
  872 #ifdef __ARM_EABI__
  873         sa->code = td->td_frame->tf_r7;
  874 #else
  875         sa->code = sa->insn & 0x000fffff;
  876 #endif
  877         ap = &td->td_frame->tf_r0;
  878         if (sa->code == SYS_syscall) {
  879                 sa->code = *ap++;
  880                 sa->nap--;
  881         } else if (sa->code == SYS___syscall) {
  882                 sa->code = ap[_QUAD_LOWWORD];
  883                 sa->nap -= 2;
  884                 ap += 2;
  885         }
  886         p = td->td_proc;
  887         if (p->p_sysent->sv_mask)
  888                 sa->code &= p->p_sysent->sv_mask;
  889         if (sa->code >= p->p_sysent->sv_size)
  890                 sa->callp = &p->p_sysent->sv_table[0];
  891         else
  892                 sa->callp = &p->p_sysent->sv_table[sa->code];
  893         sa->narg = sa->callp->sy_narg;
  894         error = 0;
  895         memcpy(sa->args, ap, sa->nap * sizeof(register_t));
  896         if (sa->narg > sa->nap) {
  897                 error = copyin((void *)td->td_frame->tf_usr_sp, sa->args +
  898                     sa->nap, (sa->narg - sa->nap) * sizeof(register_t));
  899         }
  900         if (error == 0) {
  901                 td->td_retval[0] = 0;
  902                 td->td_retval[1] = 0;
  903         }
  904         return (error);
  905 }
  906 
  907 #include "../../kern/subr_syscall.c"
  908 
  909 static void
  910 syscall(struct thread *td, trapframe_t *frame)
  911 {
  912         struct syscall_args sa;
  913         int error;
  914 
  915 #ifndef __ARM_EABI__
  916         sa.insn = *(uint32_t *)(frame->tf_pc - INSN_SIZE);
  917         switch (sa.insn & SWI_OS_MASK) {
  918         case 0: /* XXX: we need our own one. */
  919                 break;
  920         default:
  921                 call_trapsignal(td, SIGILL, 0);
  922                 userret(td, frame);
  923                 return;
  924         }
  925 #endif
  926         sa.nap = 4;
  927 
  928         error = syscallenter(td, &sa);
  929         KASSERT(error != 0 || td->td_ar == NULL,
  930             ("returning from syscall with td_ar set!"));
  931         syscallret(td, error, &sa);
  932 }
  933 
  934 void
  935 swi_handler(trapframe_t *frame)
  936 {
  937         struct thread *td = curthread;
  938 
  939         td->td_frame = frame;
  940 
  941         td->td_pticks = 0;
  942         /*
  943          * Make sure the program counter is correctly aligned so we
  944          * don't take an alignment fault trying to read the opcode.
  945          */
  946         if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
  947                 call_trapsignal(td, SIGILL, 0);
  948                 userret(td, frame);
  949                 return;
  950         }
  951         /*
  952          * Enable interrupts if they were enabled before the exception.
  953          * Since all syscalls *should* come from user mode it will always
  954          * be safe to enable them, but check anyway.
  955          */
  956         if (td->td_md.md_spinlock_count == 0) {
  957                 if (__predict_true(frame->tf_spsr & I32_bit) == 0)
  958                         enable_interrupts(I32_bit);
  959                 if (__predict_true(frame->tf_spsr & F32_bit) == 0)
  960                         enable_interrupts(F32_bit);
  961         }
  962 
  963         syscall(td, frame);
  964 }
  965 

Cache object: bdecbbab2c0eab11fe90df9553025cee


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.