1 /* $OpenBSD: syscall.c,v 1.19 2024/01/11 19:16:27 miod Exp $ */
2
3 /*
4 * Copyright (c) 2020 Brian Bamsch <bbamsch@google.com>
5 * Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/proc.h>
22 #include <sys/user.h>
23 #include <sys/syscall.h>
24 #include <sys/syscall_mi.h>
25
26 #include <uvm/uvm_extern.h>
27
28 #include <machine/syscall.h>
29
30 static __inline struct trapframe *
process_frame(struct proc * p)31 process_frame(struct proc *p)
32 {
33 return p->p_addr->u_pcb.pcb_tf;
34 }
35
36 void
svc_handler(trapframe_t * frame)37 svc_handler(trapframe_t *frame)
38 {
39 struct proc *p = curproc;
40 const struct sysent *callp = sysent;
41 int code, error = ENOSYS;
42 register_t *args, rval[2];
43
44 uvmexp.syscalls++;
45
46 code = frame->tf_t[0];
47 if (code <= 0 || code >= SYS_MAXSYSCALL)
48 goto bad;
49
50 callp += code;
51
52 args = &frame->tf_a[0];
53
54 rval[0] = 0;
55 rval[1] = 0;
56
57 error = mi_syscall(p, code, callp, args, rval);
58
59 switch (error) {
60 case 0:
61 frame->tf_a[0] = rval[0];
62 frame->tf_t[0] = 0; /* syscall succeeded */
63 break;
64 case ERESTART:
65 frame->tf_sepc -= 4; /* prev instruction */
66 break;
67 case EJUSTRETURN:
68 break;
69 default:
70 bad:
71 frame->tf_a[0] = error;
72 frame->tf_t[0] = 1; /* syscall error */
73 break;
74 }
75
76 mi_syscall_return(p, code, error, rval);
77 }
78
79 void
child_return(void * arg)80 child_return(void *arg)
81 {
82 struct proc *p = arg;
83 struct trapframe *frame = process_frame(p);
84
85 frame->tf_a[0] = 0;
86 frame->tf_t[0] = 0; /* no error */
87
88 KERNEL_UNLOCK();
89
90 mi_child_return(p);
91 }
92