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

Cache object: 96b62188200dc39e8880f5ee2069154b


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