1/* $OpenBSD: syscall.c,v 1.14 2024/01/11 19:16:27 miod Exp $ */ 2 3/* 4 * Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com> 5 * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org> 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 20#include <sys/param.h> 21#include <sys/systm.h> 22#include <sys/proc.h> 23#include <sys/user.h> 24#include <sys/syscall.h> 25#include <sys/syscall_mi.h> 26 27void 28syscall(struct trapframe *frame) 29{ 30 struct proc *p = curproc; 31 const struct sysent *callp = sysent; 32 int code, error = ENOSYS; 33 register_t *args, rval[2]; 34 35 code = frame->fixreg[0]; 36 if (code <= 0 || code >= SYS_MAXSYSCALL) 37 goto bad; 38 39 callp += code; 40 41 args = &frame->fixreg[3]; 42 43 rval[0] = 0; 44 rval[1] = 0; 45 46 error = mi_syscall(p, code, callp, args, rval); 47 48 switch (error) { 49 case 0: 50 frame->fixreg[0] = 0; 51 frame->fixreg[3] = rval[0]; 52 frame->cr &= ~0x10000000; 53 break; 54 case ERESTART: 55 frame->srr0 -= 4; 56 break; 57 case EJUSTRETURN: 58 /* nothing to do */ 59 break; 60 default: 61 bad: 62 frame->fixreg[0] = error; 63 frame->cr |= 0x10000000; 64 break; 65 } 66 67 mi_syscall_return(p, code, error, rval); 68} 69 70void 71child_return(void *arg) 72{ 73 struct proc *p = (struct proc *)arg; 74 struct trapframe *frame = p->p_md.md_regs; 75 76 frame->fixreg[0] = 0; 77 frame->fixreg[3] = 0; 78 frame->cr &= ~0x10000000; 79 80 KERNEL_UNLOCK(); 81 82 mi_child_return(p); 83} 84