Home | History | Annotate | Line # | Download | only in vax
      1 /*	$NetBSD: syscall.c,v 1.27 2023/10/05 19:41:06 ad Exp $     */
      2 
      3 /*
      4  * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28  /* All bugs are subject to removal without further notice */
     29 
     30 #include <sys/cdefs.h>
     31 __KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.27 2023/10/05 19:41:06 ad Exp $");
     32 
     33 #include "opt_multiprocessor.h"
     34 
     35 #include <sys/param.h>
     36 #include <sys/systm.h>
     37 #include <sys/cpu.h>
     38 #include <sys/ktrace.h>
     39 #include <sys/proc.h>
     40 #include <sys/syscall.h>
     41 #include <sys/syscallvar.h>
     42 
     43 #include <machine/userret.h>
     44 
     45 #ifdef TRAPDEBUG
     46 int startsysc = 0;
     47 #define TDB(a) if (startsysc) printf a
     48 #else
     49 #define TDB(a)
     50 #endif
     51 
     52 void syscall(struct trapframe *);
     53 
     54 void
     55 syscall_intern(struct proc *p)
     56 {
     57 	p->p_trace_enabled = trace_is_enabled(p);
     58 	p->p_md.md_syscall = syscall;
     59 }
     60 
     61 void
     62 syscall(struct trapframe *tf)
     63 {
     64 	int error;
     65 	int rval[2];
     66 	int args[2+SYS_MAXSYSARGS]; /* add two for SYS___syscall + padding */
     67 	struct lwp * const l = curlwp;
     68 	struct proc * const p = l->l_proc;
     69 	const struct emul * const emul = p->p_emul;
     70 	const struct sysent *callp = emul->e_sysent;
     71 	const u_quad_t oticks = p->p_sticks;
     72 
     73 	TDB(("trap syscall %s pc %lx, psl %lx, sp %lx, pid %d, frame %p\n",
     74 	    syscallnames[tf->tf_code], tf->tf_pc, tf->tf_psl,tf->tf_sp,
     75 	    p->p_pid,tf));
     76 
     77 	curcpu()->ci_data.cpu_nsyscall++;
     78 
     79 	l->l_md.md_utf = tf;
     80 
     81 	if ((unsigned long) tf->tf_code >= emul->e_nsysent)
     82 		callp += emul->e_nosys;
     83 	else
     84 		callp += tf->tf_code;
     85 
     86 	rval[0] = 0;
     87 	rval[1] = tf->tf_r1;
     88 
     89 	if (callp->sy_narg) {
     90 		error = copyin((char*)tf->tf_ap + 4, args, callp->sy_argsize);
     91 		if (error)
     92 			goto bad;
     93 	}
     94 
     95 	/*
     96 	 * Only trace if tracing is enabled and the syscall isn't indirect
     97 	 * (SYS_syscall or SYS___syscall)
     98 	 */
     99 	error = sy_invoke(callp, curlwp, args, rval, tf->tf_code);
    100 
    101 	TDB(("return %s pc %lx, psl %lx, sp %lx, pid %d, err %d r0 %d, r1 %d, "
    102 	    "tf %p\n", syscallnames[tf->tf_code], tf->tf_pc, tf->tf_psl,
    103 	    tf->tf_sp, p->p_pid, error, rval[0], rval[1], tf));
    104 bad:
    105 	switch (error) {
    106 	case 0:
    107 		tf->tf_r1 = rval[1];
    108 		tf->tf_r0 = rval[0];
    109 		tf->tf_psl &= ~PSL_C;
    110 		break;
    111 
    112 	case EJUSTRETURN:
    113 		break;
    114 
    115 	case ERESTART:
    116 		/* assumes CHMK $n was used */
    117 		tf->tf_pc -= (tf->tf_code > 63 ? 4 : 2);
    118 		break;
    119 
    120 	default:
    121 		tf->tf_r0 = error;
    122 		tf->tf_psl |= PSL_C;
    123 		break;
    124 	}
    125 
    126 	userret(l, tf, oticks);
    127 }
    128 
    129 void
    130 md_child_return(struct lwp *l)
    131 {
    132 
    133 	userret(l, l->l_md.md_utf, 0);
    134 }
    135 
    136 /*
    137  * Process the tail end of a posix_spawn() for the child.
    138  */
    139 void
    140 cpu_spawn_return(struct lwp *l)
    141 {
    142 
    143 	userret(l, l->l_md.md_utf, 0);
    144 }
    145