Home | History | Annotate | Line # | Download | only in kern
sys_syscall.c revision 1.16
      1 /*	$NetBSD: sys_syscall.c,v 1.16 2025/06/01 23:30:36 bad Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by David Laight.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __KERNEL_RCSID(0, "$NetBSD: sys_syscall.c,v 1.16 2025/06/01 23:30:36 bad Exp $");
     34 
     35 #include <sys/syscall_stats.h>
     36 #include <sys/syscallvar.h>
     37 
     38 /*
     39  * MI indirect system call support.
     40  * Included from sys_scdebug.c and compat/netbsd32/netbsd32_indirect.c
     41  *
     42  * SYS_SYSCALL is set to the required function name.
     43  */
     44 
     45 #define CONCAT(a,b) __CONCAT(a,b)
     46 
     47 static void
     48 CONCAT(SYS_SYSCALL, _biglockcheck)(struct proc *p, int code)
     49 {
     50 
     51 #ifdef DIAGNOSTIC
     52        kpreempt_disable();     /* make curcpu() stable */
     53        KASSERTMSG(curcpu()->ci_biglock_count == 0,
     54            "syscall %ld of emul %s leaked %d kernel locks",
     55            (long)code, p->p_emul->e_name, curcpu()->ci_biglock_count);
     56        kpreempt_enable();
     57 #endif
     58 }
     59 
     60 int
     61 SYS_SYSCALL(struct lwp *l, const struct CONCAT(SYS_SYSCALL, _args) *uap,
     62     register_t *rval)
     63 {
     64 	/* {
     65 		syscallarg(int) code;
     66 		syscallarg(register_t) args[SYS_MAXSYSARGS];
     67 	} */
     68 	const struct sysent *callp;
     69 	struct proc *p = l->l_proc;
     70 	int code;
     71 	int error;
     72 #ifdef NETBSD32_SYSCALL
     73 	register_t args64[SYS_MAXSYSARGS];
     74 	int i, narg;
     75 	#define TRACE_ARGS args64
     76 #else
     77 	#define TRACE_ARGS &SCARG(uap, args[0])
     78 #endif
     79 
     80 	callp = p->p_emul->e_sysent;
     81 
     82 	code = SCARG(uap, code) & (SYS_NSYSENT - 1);
     83 	SYSCALL_COUNT(syscall_counts, code);
     84 	callp += code;
     85 
     86 	if (__predict_false(callp->sy_flags & SYCALL_INDIRECT))
     87 		return ENOSYS;
     88 
     89 	if (__predict_true(!p->p_trace_enabled)) {
     90 		error = sy_call(callp, l, &uap->args, rval);
     91 		CONCAT(SYS_SYSCALL, _biglockcheck)(p, code);
     92 		return error;
     93 	}
     94 
     95 #ifdef NETBSD32_SYSCALL
     96 	narg = callp->sy_narg;
     97 	for (i = 0; i < narg; i++)
     98 		args64[i] = SCARG(uap, args[i]);
     99 #endif
    100 
    101 	error = trace_enter(code, callp, TRACE_ARGS);
    102 	if (__predict_true(error == 0))
    103 		error = sy_call(callp, l, &uap->args, rval);
    104 	trace_exit(code, callp, &uap->args, rval, error);
    105 	CONCAT(SYS_SYSCALL, _biglockcheck)(p, code);
    106 	return error;
    107 
    108 	#undef TRACE_ARGS
    109 }
    110