Home | History | Annotate | Line # | Download | only in alpha
      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(), &copyargs[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