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