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/sparc64/sparc64/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 /*-
    2  * Copyright (c) 2001, Jake Burkholder
    3  * Copyright (C) 1994, David Greenman
    4  * Copyright (c) 1990, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * This code is derived from software contributed to Berkeley by
    8  * the University of Utah, and William Jolitz.
    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 by the University of
   21  *      California, Berkeley and its contributors.
   22  * 4. Neither the name of the University nor the names of its contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  *      from: @(#)trap.c        7.4 (Berkeley) 5/13/91
   39  *      from: FreeBSD: src/sys/i386/i386/trap.c,v 1.197 2001/07/19
   40  */
   41 
   42 #include <sys/cdefs.h>
   43 __FBSDID("$FreeBSD$");
   44 
   45 #include "opt_ddb.h"
   46 #include "opt_ktr.h"
   47 #include "opt_ktrace.h"
   48 
   49 #include <sys/param.h>
   50 #include <sys/kdb.h>
   51 #include <sys/kernel.h>
   52 #include <sys/bus.h>
   53 #include <sys/interrupt.h>
   54 #include <sys/ktr.h>
   55 #include <sys/lock.h>
   56 #include <sys/mutex.h>
   57 #include <sys/systm.h>
   58 #include <sys/pioctl.h>
   59 #include <sys/ptrace.h>
   60 #include <sys/proc.h>
   61 #include <sys/smp.h>
   62 #include <sys/signalvar.h>
   63 #include <sys/syscall.h>
   64 #include <sys/sysctl.h>
   65 #include <sys/sysent.h>
   66 #include <sys/vmmeter.h>
   67 #ifdef KTRACE
   68 #include <sys/uio.h>
   69 #include <sys/ktrace.h>
   70 #endif
   71 #include <security/audit/audit.h>
   72 
   73 #include <vm/vm.h>
   74 #include <vm/pmap.h>
   75 #include <vm/vm_extern.h>
   76 #include <vm/vm_param.h>
   77 #include <vm/vm_kern.h>
   78 #include <vm/vm_map.h>
   79 #include <vm/vm_page.h>
   80 
   81 #include <machine/cpu.h>
   82 #include <machine/frame.h>
   83 #include <machine/intr_machdep.h>
   84 #include <machine/pcb.h>
   85 #include <machine/smp.h>
   86 #include <machine/trap.h>
   87 #include <machine/tstate.h>
   88 #include <machine/tte.h>
   89 #include <machine/tlb.h>
   90 #include <machine/tsb.h>
   91 #include <machine/watch.h>
   92 
   93 void trap(struct trapframe *tf);
   94 void syscall(struct trapframe *tf);
   95 
   96 static int trap_pfault(struct thread *td, struct trapframe *tf);
   97 
   98 extern char copy_fault[];
   99 extern char copy_nofault_begin[];
  100 extern char copy_nofault_end[];
  101 
  102 extern char fs_fault[];
  103 extern char fs_nofault_begin[];
  104 extern char fs_nofault_end[];
  105 extern char fs_nofault_intr_begin[];
  106 extern char fs_nofault_intr_end[];
  107 
  108 extern char fas_fault[];
  109 extern char fas_nofault_begin[];
  110 extern char fas_nofault_end[];
  111 
  112 extern char *syscallnames[];
  113 
  114 const char *trap_msg[] = {
  115         "reserved",
  116         "instruction access exception",
  117         "instruction access error",
  118         "instruction access protection",
  119         "illtrap instruction",
  120         "illegal instruction",
  121         "privileged opcode",
  122         "floating point disabled",
  123         "floating point exception ieee 754",
  124         "floating point exception other",
  125         "tag overflow",
  126         "division by zero",
  127         "data access exception",
  128         "data access error",
  129         "data access protection",
  130         "memory address not aligned",
  131         "privileged action",
  132         "async data error",
  133         "trap instruction 16",
  134         "trap instruction 17",
  135         "trap instruction 18",
  136         "trap instruction 19",
  137         "trap instruction 20",
  138         "trap instruction 21",
  139         "trap instruction 22",
  140         "trap instruction 23",
  141         "trap instruction 24",
  142         "trap instruction 25",
  143         "trap instruction 26",
  144         "trap instruction 27",
  145         "trap instruction 28",
  146         "trap instruction 29",
  147         "trap instruction 30",
  148         "trap instruction 31",
  149         "fast instruction access mmu miss",
  150         "fast data access mmu miss",
  151         "interrupt",
  152         "physical address watchpoint",
  153         "virtual address watchpoint",
  154         "corrected ecc error",
  155         "spill",
  156         "fill",
  157         "fill",
  158         "breakpoint",
  159         "clean window",
  160         "range check",
  161         "fix alignment",
  162         "integer overflow",
  163         "syscall",
  164         "restore physical watchpoint",
  165         "restore virtual watchpoint",
  166         "kernel stack fault",
  167 };
  168 
  169 static const int trap_sig[] = {
  170         SIGILL,                 /* reserved */
  171         SIGILL,                 /* instruction access exception */
  172         SIGILL,                 /* instruction access error */
  173         SIGILL,                 /* instruction access protection */
  174         SIGILL,                 /* illtrap instruction */
  175         SIGILL,                 /* illegal instruction */
  176         SIGBUS,                 /* privileged opcode */
  177         SIGFPE,                 /* floating point disabled */
  178         SIGFPE,                 /* floating point exception ieee 754 */
  179         SIGFPE,                 /* floating point exception other */
  180         SIGEMT,                 /* tag overflow */
  181         SIGFPE,                 /* division by zero */
  182         SIGILL,                 /* data access exception */
  183         SIGILL,                 /* data access error */
  184         SIGBUS,                 /* data access protection */
  185         SIGBUS,                 /* memory address not aligned */
  186         SIGBUS,                 /* privileged action */
  187         SIGBUS,                 /* async data error */
  188         SIGILL,                 /* trap instruction 16 */
  189         SIGILL,                 /* trap instruction 17 */
  190         SIGILL,                 /* trap instruction 18 */
  191         SIGILL,                 /* trap instruction 19 */
  192         SIGILL,                 /* trap instruction 20 */
  193         SIGILL,                 /* trap instruction 21 */
  194         SIGILL,                 /* trap instruction 22 */
  195         SIGILL,                 /* trap instruction 23 */
  196         SIGILL,                 /* trap instruction 24 */
  197         SIGILL,                 /* trap instruction 25 */
  198         SIGILL,                 /* trap instruction 26 */
  199         SIGILL,                 /* trap instruction 27 */
  200         SIGILL,                 /* trap instruction 28 */
  201         SIGILL,                 /* trap instruction 29 */
  202         SIGILL,                 /* trap instruction 30 */
  203         SIGILL,                 /* trap instruction 31 */
  204         SIGSEGV,                /* fast instruction access mmu miss */
  205         SIGSEGV,                /* fast data access mmu miss */
  206         -1,                     /* interrupt */
  207         -1,                     /* physical address watchpoint */
  208         -1,                     /* virtual address watchpoint */
  209         -1,                     /* corrected ecc error */
  210         SIGILL,                 /* spill */
  211         SIGILL,                 /* fill */
  212         SIGILL,                 /* fill */
  213         SIGTRAP,                /* breakpoint */
  214         SIGILL,                 /* clean window */
  215         SIGILL,                 /* range check */
  216         SIGILL,                 /* fix alignment */
  217         SIGILL,                 /* integer overflow */
  218         SIGSYS,                 /* syscall */
  219         -1,                     /* restore physical watchpoint */
  220         -1,                     /* restore virtual watchpoint */
  221         -1,                     /* kernel stack fault */
  222 };
  223 
  224 CTASSERT(sizeof(struct trapframe) == 256);
  225 
  226 int debugger_on_signal = 0;
  227 SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW,
  228     &debugger_on_signal, 0, "");
  229 
  230 void
  231 trap(struct trapframe *tf)
  232 {
  233         struct thread *td;
  234         struct proc *p;
  235         int error;
  236         int sig;
  237         register_t addr;
  238         ksiginfo_t ksi;
  239 
  240         td = PCPU_GET(curthread);
  241 
  242         CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td,
  243             trap_msg[tf->tf_type & ~T_KERNEL],
  244             (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil));
  245 
  246         PCPU_INC(cnt.v_trap);
  247 
  248         if ((tf->tf_tstate & TSTATE_PRIV) == 0) {
  249                 KASSERT(td != NULL, ("trap: curthread NULL"));
  250                 KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
  251 
  252                 p = td->td_proc;
  253                 td->td_pticks = 0;
  254                 td->td_frame = tf;
  255                 addr = tf->tf_tpc;
  256                 if (td->td_ucred != p->p_ucred)
  257                         cred_update_thread(td);
  258 
  259                 switch (tf->tf_type) {
  260                 case T_DATA_MISS:
  261                 case T_DATA_PROTECTION:
  262                         addr = tf->tf_sfar;
  263                         /* FALLTHROUGH */
  264                 case T_INSTRUCTION_MISS:
  265                         sig = trap_pfault(td, tf);
  266                         break;
  267                 case T_FILL:
  268                         sig = rwindow_load(td, tf, 2);
  269                         break;
  270                 case T_FILL_RET:
  271                         sig = rwindow_load(td, tf, 1);
  272                         break;
  273                 case T_SPILL:
  274                         sig = rwindow_save(td);
  275                         break;
  276                 default:
  277                         if (tf->tf_type < 0 || tf->tf_type >= T_MAX ||
  278                             trap_sig[tf->tf_type] == -1)
  279                                 panic("trap: bad trap type");
  280                         sig = trap_sig[tf->tf_type];
  281                         break;
  282                 }
  283 
  284                 if (sig != 0) {
  285                         /* Translate fault for emulators. */
  286                         if (p->p_sysent->sv_transtrap != NULL) {
  287                                 sig = p->p_sysent->sv_transtrap(sig,
  288                                     tf->tf_type);
  289                         }
  290                         if (debugger_on_signal &&
  291                             (sig == 4 || sig == 10 || sig == 11))
  292                                 kdb_enter("trapsig");
  293                         ksiginfo_init_trap(&ksi);
  294                         ksi.ksi_signo = sig;
  295                         ksi.ksi_code = (int)tf->tf_type; /* XXX not POSIX */
  296                         ksi.ksi_addr = (void *)addr;
  297                         ksi.ksi_trapno = (int)tf->tf_type;
  298                         trapsignal(td, &ksi);
  299                 }
  300 
  301                 userret(td, tf);
  302                 mtx_assert(&Giant, MA_NOTOWNED);
  303         } else {
  304                 KASSERT((tf->tf_type & T_KERNEL) != 0,
  305                     ("trap: kernel trap isn't"));
  306 
  307 #ifdef KDB
  308                 if (kdb_active) {
  309                         kdb_reenter();
  310                         return;
  311                 }
  312 #endif
  313 
  314                 switch (tf->tf_type & ~T_KERNEL) {
  315 #ifdef KDB
  316                 case T_BREAKPOINT:
  317                 case T_KSTACK_FAULT:
  318                         error = (kdb_trap(tf->tf_type, 0, tf) == 0);
  319                         TF_DONE(tf);
  320                         break;
  321 #ifdef notyet
  322                 case T_PA_WATCHPOINT:
  323                 case T_VA_WATCHPOINT:
  324                         error = db_watch_trap(tf);
  325                         break;
  326 #endif
  327 #endif
  328                 case T_DATA_MISS:
  329                 case T_DATA_PROTECTION:
  330                 case T_INSTRUCTION_MISS:
  331                         error = trap_pfault(td, tf);
  332                         break;
  333                 case T_DATA_EXCEPTION:
  334                 case T_MEM_ADDRESS_NOT_ALIGNED:
  335                         if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 &&
  336                             MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) {
  337                                 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
  338                                     tf->tf_tpc <= (u_long)copy_nofault_end) {
  339                                         tf->tf_tpc = (u_long)copy_fault;
  340                                         tf->tf_tnpc = tf->tf_tpc + 4;
  341                                         error = 0;
  342                                         break;
  343                                 }
  344                                 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
  345                                     tf->tf_tpc <= (u_long)fs_nofault_end) {
  346                                         tf->tf_tpc = (u_long)fs_fault;
  347                                         tf->tf_tnpc = tf->tf_tpc + 4;
  348                                         error = 0;
  349                                         break;
  350                                 }
  351                         }
  352                         error = 1;      
  353                         break;
  354                 case T_DATA_ERROR:
  355                         /*
  356                          * Handle PCI poke/peek as per UltraSPARC IIi
  357                          * User's Manual 16.2.1, modulo checking the
  358                          * TPC as USIII CPUs generate a precise trap
  359                          * instead of a special deferred one.
  360                          */
  361                         if (tf->tf_tpc > (u_long)fas_nofault_begin &&
  362                             tf->tf_tpc < (u_long)fas_nofault_end) {
  363                                 cache_flush();
  364                                 cache_enable();
  365                                 tf->tf_tpc = (u_long)fas_fault;
  366                                 tf->tf_tnpc = tf->tf_tpc + 4;
  367                                 error = 0;
  368                                 break;
  369                         }
  370                         error = 1;
  371                         break;
  372                 default:
  373                         error = 1;
  374                         break;
  375                 }
  376 
  377                 if (error != 0)
  378                         panic("trap: %s", trap_msg[tf->tf_type & ~T_KERNEL]);
  379         }
  380         CTR1(KTR_TRAP, "trap: td=%p return", td);
  381 }
  382 
  383 static int
  384 trap_pfault(struct thread *td, struct trapframe *tf)
  385 {
  386         struct vmspace *vm;
  387         struct pcb *pcb;
  388         struct proc *p;
  389         vm_offset_t va;
  390         vm_prot_t prot;
  391         u_long ctx;
  392         int flags;
  393         int type;
  394         int rv;
  395 
  396         if (td == NULL)
  397                 return (-1);
  398         KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL"));
  399         KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL"));
  400         KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL"));
  401 
  402         p = td->td_proc;
  403 
  404         rv = KERN_SUCCESS;
  405         ctx = TLB_TAR_CTX(tf->tf_tar);
  406         pcb = td->td_pcb;
  407         type = tf->tf_type & ~T_KERNEL;
  408         va = TLB_TAR_VA(tf->tf_tar);
  409 
  410         CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx",
  411             td, p->p_vmspace->vm_pmap.pm_context[PCPU_GET(cpuid)], va, ctx);
  412 
  413         if (type == T_DATA_PROTECTION) {
  414                 prot = VM_PROT_WRITE;
  415                 flags = VM_FAULT_DIRTY;
  416         } else {
  417                 if (type == T_DATA_MISS)
  418                         prot = VM_PROT_READ;
  419                 else
  420                         prot = VM_PROT_READ | VM_PROT_EXECUTE;
  421                 flags = VM_FAULT_NORMAL;
  422         }
  423 
  424         if (ctx != TLB_CTX_KERNEL) {
  425                 if ((tf->tf_tstate & TSTATE_PRIV) != 0 &&
  426                     (tf->tf_tpc >= (u_long)fs_nofault_intr_begin &&
  427                      tf->tf_tpc <= (u_long)fs_nofault_intr_end)) {
  428                         tf->tf_tpc = (u_long)fs_fault;
  429                         tf->tf_tnpc = tf->tf_tpc + 4;
  430                         return (0);
  431                 }
  432 
  433                 /*
  434                  * This is a fault on non-kernel virtual memory.
  435                  */
  436                 vm = p->p_vmspace;
  437 
  438                 /*
  439                  * Keep swapout from messing with us during this
  440                  * critical time.
  441                  */
  442                 PROC_LOCK(p);
  443                 ++p->p_lock;
  444                 PROC_UNLOCK(p);
  445 
  446                 /* Fault in the user page. */
  447                 rv = vm_fault(&vm->vm_map, va, prot, flags);
  448 
  449                 /*
  450                  * Now the process can be swapped again.
  451                  */
  452                 PROC_LOCK(p);
  453                 --p->p_lock;
  454                 PROC_UNLOCK(p);
  455         } else {
  456                 /*
  457                  * This is a fault on kernel virtual memory.  Attempts to
  458                  * access kernel memory from user mode cause privileged
  459                  * action traps, not page fault.
  460                  */
  461                 KASSERT(tf->tf_tstate & TSTATE_PRIV,
  462                     ("trap_pfault: fault on nucleus context from user mode"));
  463 
  464                 /*
  465                  * Don't have to worry about process locking or stacks in the
  466                  * kernel.
  467                  */
  468                 rv = vm_fault(kernel_map, va, prot, VM_FAULT_NORMAL);
  469         }
  470 
  471         CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d",
  472             td, va, rv);
  473         if (rv == KERN_SUCCESS)
  474                 return (0);
  475         if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) {
  476                 if (tf->tf_tpc >= (u_long)fs_nofault_begin &&
  477                     tf->tf_tpc <= (u_long)fs_nofault_end) {
  478                         tf->tf_tpc = (u_long)fs_fault;
  479                         tf->tf_tnpc = tf->tf_tpc + 4;
  480                         return (0);
  481                 }
  482                 if (tf->tf_tpc >= (u_long)copy_nofault_begin &&
  483                     tf->tf_tpc <= (u_long)copy_nofault_end) {
  484                         tf->tf_tpc = (u_long)copy_fault;
  485                         tf->tf_tnpc = tf->tf_tpc + 4;
  486                         return (0);
  487                 }
  488         }
  489         return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
  490 }
  491 
  492 /* Maximum number of arguments that can be passed via the out registers. */
  493 #define REG_MAXARGS     6
  494 
  495 /*
  496  * Syscall handler. The arguments to the syscall are passed in the o registers
  497  * by the caller, and are saved in the trap frame. The syscall number is passed
  498  * in %g1 (and also saved in the trap frame).
  499  */
  500 void
  501 syscall(struct trapframe *tf)
  502 {
  503         struct sysent *callp;
  504         struct thread *td;
  505         register_t args[8];
  506         register_t *argp;
  507         struct proc *p;
  508         u_long code;
  509         u_long tpc;
  510         int reg;
  511         int regcnt;
  512         int narg;
  513         int error;
  514 
  515         td = PCPU_GET(curthread);
  516         KASSERT(td != NULL, ("trap: curthread NULL"));
  517         KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
  518 
  519         p = td->td_proc;
  520 
  521         PCPU_INC(cnt.v_syscall);
  522 
  523         narg = 0;
  524         error = 0;
  525         reg = 0;
  526         regcnt = REG_MAXARGS;
  527 
  528         td->td_pticks = 0;
  529         td->td_frame = tf;
  530         if (td->td_ucred != p->p_ucred)
  531                 cred_update_thread(td);
  532 #ifdef KSE
  533         if (p->p_flag & P_SA)
  534                 thread_user_enter(td);
  535 #endif
  536         code = tf->tf_global[1];
  537 
  538         /*
  539          * For syscalls, we don't want to retry the faulting instruction
  540          * (usually), instead we need to advance one instruction.
  541          */
  542         tpc = tf->tf_tpc;
  543         TF_DONE(tf);
  544 
  545         if (p->p_sysent->sv_prepsyscall) {
  546                 /*
  547                  * The prep code is MP aware.
  548                  */
  549 #if 0
  550                 (*p->p_sysent->sv_prepsyscall)(tf, args, &code, &params);
  551 #endif  
  552         } else  if (code == SYS_syscall || code == SYS___syscall) {
  553                 code = tf->tf_out[reg++];
  554                 regcnt--;
  555         }
  556 
  557         if (p->p_sysent->sv_mask)
  558                 code &= p->p_sysent->sv_mask;
  559 
  560         if (code >= p->p_sysent->sv_size)
  561                 callp = &p->p_sysent->sv_table[0];
  562         else
  563                 callp = &p->p_sysent->sv_table[code];
  564 
  565         narg = callp->sy_narg;
  566 
  567         if (narg <= regcnt) {
  568                 argp = &tf->tf_out[reg];
  569                 error = 0;
  570         } else {
  571                 KASSERT(narg <= sizeof(args) / sizeof(args[0]),
  572                     ("Too many syscall arguments!"));
  573                 argp = args;
  574                 bcopy(&tf->tf_out[reg], args, sizeof(args[0]) * regcnt);
  575                 error = copyin((void *)(tf->tf_out[6] + SPOFF +
  576                     offsetof(struct frame, fr_pad[6])),
  577                     &args[regcnt], (narg - regcnt) * sizeof(args[0]));
  578         }
  579 
  580         CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td,
  581             syscallnames[code], argp[0], argp[1], argp[2]);
  582 
  583 #ifdef KTRACE
  584         if (KTRPOINT(td, KTR_SYSCALL))
  585                 ktrsyscall(code, narg, argp);
  586 #endif
  587 
  588         td->td_syscalls++;
  589 
  590         if (error == 0) {
  591                 td->td_retval[0] = 0;
  592                 td->td_retval[1] = 0;
  593 
  594                 STOPEVENT(p, S_SCE, narg);      /* MP aware */
  595 
  596                 PTRACESTOP_SC(p, td, S_PT_SCE);
  597 
  598                 AUDIT_SYSCALL_ENTER(code, td);
  599                 error = (*callp->sy_call)(td, argp);
  600                 AUDIT_SYSCALL_EXIT(error, td);
  601 
  602                 CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx ", p,
  603                     error, syscallnames[code], td->td_retval[0],
  604                     td->td_retval[1]);
  605         }
  606         
  607         /*
  608          * MP SAFE (we may or may not have the MP lock at this point)
  609          */
  610         switch (error) {
  611         case 0:
  612                 tf->tf_out[0] = td->td_retval[0];
  613                 tf->tf_out[1] = td->td_retval[1];
  614                 tf->tf_tstate &= ~TSTATE_XCC_C;
  615                 break;
  616 
  617         case ERESTART:
  618                 /*
  619                  * Undo the tpc advancement we have done above, we want to
  620                  * reexecute the system call.
  621                  */
  622                 tf->tf_tpc = tpc;
  623                 tf->tf_tnpc -= 4;
  624                 break;
  625 
  626         case EJUSTRETURN:
  627                 break;
  628 
  629         default:
  630                 if (p->p_sysent->sv_errsize) {
  631                         if (error >= p->p_sysent->sv_errsize)
  632                                 error = -1;     /* XXX */
  633                         else
  634                                 error = p->p_sysent->sv_errtbl[error];
  635                 }
  636                 tf->tf_out[0] = error;
  637                 tf->tf_tstate |= TSTATE_XCC_C;
  638                 break;
  639         }
  640 
  641         /*
  642          * Check for misbehavior.
  643          */
  644         WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
  645             (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");
  646         KASSERT(td->td_critnest == 0,
  647             ("System call %s returning in a critical section",
  648             (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"));
  649         KASSERT(td->td_locks == 0,
  650             ("System call %s returning with %d locks held",
  651             (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???",
  652             td->td_locks));
  653 
  654         /*
  655          * Handle reschedule and other end-of-syscall issues
  656          */
  657         userret(td, tf);
  658 
  659 #ifdef KTRACE
  660         if (KTRPOINT(td, KTR_SYSRET))
  661                 ktrsysret(code, error, td->td_retval[0]);
  662 #endif
  663         /*
  664          * This works because errno is findable through the
  665          * register set.  If we ever support an emulation where this
  666          * is not the case, this code will need to be revisited.
  667          */
  668         STOPEVENT(p, S_SCX, code);
  669 
  670         PTRACESTOP_SC(p, td, S_PT_SCX);
  671 }

Cache object: 927c03aa61eaf492cf24fe03f7610e65


[ 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.