1 /* $NetBSD: syscall.c,v 1.46 2026/05/10 23:51:37 tls Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center, and by Charles M. Hannum. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1999 Christopher G. Demetriou. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by Christopher G. Demetriou 47 * for the NetBSD Project. 48 * 4. The name of the author may not be used to endorse or promote products 49 * derived from this software without specific prior written permission 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 53 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 54 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 55 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 60 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 */ 62 63 /* 64 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 65 * All rights reserved. 66 * 67 * Author: Chris G. Demetriou 68 * 69 * Permission to use, copy, modify and distribute this software and 70 * its documentation is hereby granted, provided that both the copyright 71 * notice and this permission notice appear in all copies of the 72 * software, derivative works or modified versions, and any portions 73 * thereof, and that both notices appear in supporting documentation. 74 * 75 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 76 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 77 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 78 * 79 * Carnegie Mellon requests users of this software to return to 80 * 81 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU 82 * School of Computer Science 83 * Carnegie Mellon University 84 * Pittsburgh PA 15213-3890 85 * 86 * any improvements or extensions that they make and grant Carnegie the 87 * rights to redistribute these changes. 88 */ 89 90 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 91 92 __KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.46 2026/05/10 23:51:37 tls Exp $"); 93 94 #include <sys/param.h> 95 #include <sys/systm.h> 96 #include <sys/proc.h> 97 #include <sys/signal.h> 98 #include <sys/syscall.h> 99 #include <sys/syscallvar.h> 100 #include <sys/ktrace.h> 101 102 #include <machine/cpu.h> 103 #include <machine/reg.h> 104 #include <machine/alpha.h> 105 #include <machine/userret.h> 106 107 void syscall(struct lwp *, uint64_t, struct trapframe *); 108 109 void 110 syscall_intern(struct proc *p) 111 { 112 113 p->p_md.md_syscall = syscall; 114 } 115 116 /* 117 * Process a system call. 118 * 119 * System calls are strange beasts. They are passed the syscall number 120 * in v0, and the arguments in the registers (as normal). They return 121 * an error flag in a3 (if a3 != 0 on return, the syscall had an error), 122 * and the return value (if any) in v0. 123 * 124 * The assembly stub takes care of moving the call number into a register 125 * we can get to, and moves all of the argument registers into their places 126 * in the trap frame. On return, it restores the callee-saved registers, 127 * a3, and v0 from the frame before returning to the user process. 128 */ 129 130 void 131 syscall(struct lwp *l, uint64_t code, struct trapframe *tf) 132 { 133 const struct sysent *callp; 134 int error; 135 uint64_t rval[2]; 136 uint64_t *args, copyargs[10]; 137 u_int hidden, nargs; 138 struct proc * const p = l->l_proc; 139 140 curcpu()->ci_data.cpu_nsyscall++; 141 l->l_md.md_tf = tf; 142 143 callp = p->p_emul->e_sysent; 144 145 switch (code) { 146 case SYS_syscall: 147 case SYS___syscall: 148 /* 149 * syscall() and __syscall() are handled the same on 150 * the alpha, as everything is 64-bit aligned, anyway. 151 */ 152 code = tf->tf_regs[FRAME_A0]; 153 hidden = 1; 154 break; 155 default: 156 hidden = 0; 157 break; 158 } 159 160 code &= (SYS_NSYSENT - 1); 161 callp += code; 162 163 nargs = callp->sy_narg + hidden; 164 switch (nargs) { 165 default: 166 error = copyin((void *)alpha_pal_rdusp(), ©args[6], 167 (nargs - 6) * sizeof(uint64_t)); 168 if (error) { 169 goto bad; 170 } 171 case 6: 172 copyargs[5] = tf->tf_regs[FRAME_A5]; 173 case 5: 174 copyargs[4] = tf->tf_regs[FRAME_A4]; 175 case 4: 176 copyargs[3] = tf->tf_regs[FRAME_A3]; 177 copyargs[2] = tf->tf_regs[FRAME_A2]; 178 copyargs[1] = tf->tf_regs[FRAME_A1]; 179 copyargs[0] = tf->tf_regs[FRAME_A0]; 180 args = copyargs; 181 break; 182 case 3: 183 case 2: 184 case 1: 185 case 0: 186 args = &tf->tf_regs[FRAME_A0]; 187 break; 188 } 189 args += hidden; 190 191 error = sy_invoke(callp, l, args, rval, code); 192 193 if (__predict_true(error == 0)) { 194 /* 195 * Sign-extend 32-bit syscall return values to 64 bits, 196 * as required by ABI. Avoids corruption if the returned 197 * value is spilled to and reloaded from the stack in 198 * userspace. 199 */ 200 if (!SYCALL_RET_WIDE_P(callp)) { 201 rval[0] = (int32_t)(int64_t)rval[0]; 202 rval[1] = (int32_t)(int64_t)rval[1]; 203 } 204 tf->tf_regs[FRAME_V0] = rval[0]; 205 tf->tf_regs[FRAME_A4] = rval[1]; 206 tf->tf_regs[FRAME_A3] = 0; 207 } else { 208 switch (error) { 209 case ERESTART: 210 tf->tf_regs[FRAME_PC] -= 4; 211 break; 212 case EJUSTRETURN: 213 break; 214 default: 215 bad: 216 tf->tf_regs[FRAME_V0] = error; 217 tf->tf_regs[FRAME_A3] = 1; 218 break; 219 } 220 } 221 222 userret(l); 223 } 224 225 /* 226 * Process the tail end of a fork() for the child. 227 */ 228 void 229 md_child_return(struct lwp *l) 230 { 231 232 /* 233 * Return values in the frame set by cpu_lwp_fork(). 234 */ 235 userret(l); 236 } 237 238 /* 239 * Process the tail end of a posix_spawn() for the child. 240 */ 241 void 242 cpu_spawn_return(struct lwp *l) 243 { 244 245 userret(l); 246 } 247