xref: /netbsd-src/sys/arch/vax/vax/syscall.c (revision 68fa58437753598de948829082f591c269b48777)
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
syscall_intern(struct proc * p)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
syscall(struct trapframe * tf)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
md_child_return(struct lwp * l)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
cpu_spawn_return(struct lwp * l)140 cpu_spawn_return(struct lwp *l)
141 {
142 
143 	userret(l, l->l_md.md_utf, 0);
144 }
145