xref: /openbsd/sys/arch/arm64/arm64/syscall.c (revision 82f13a27)
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