xref: /freebsd/sys/kern/kern_syscalls.c (revision 46db48360da3dd2101630af93cb6fcbb9f21eab3)
14c3df794SDoug Rabson /*-
24c3df794SDoug Rabson  * Copyright (c) 1999 Assar Westerlund
34c3df794SDoug Rabson  * All rights reserved.
44c3df794SDoug Rabson  *
54c3df794SDoug Rabson  * Redistribution and use in source and binary forms, with or without
64c3df794SDoug Rabson  * modification, are permitted provided that the following conditions
74c3df794SDoug Rabson  * are met:
84c3df794SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
94c3df794SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
104c3df794SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
114c3df794SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
124c3df794SDoug Rabson  *    documentation and/or other materials provided with the distribution.
134c3df794SDoug Rabson  *
144c3df794SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
154c3df794SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
164c3df794SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
174c3df794SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
184c3df794SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
194c3df794SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
204c3df794SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
214c3df794SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
224c3df794SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
234c3df794SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
244c3df794SDoug Rabson  * SUCH DAMAGE.
254c3df794SDoug Rabson  *
2646db4836SPeter Wemm  *     $Id: kern_syscalls.c,v 1.2 1999/01/09 14:59:50 dfr Exp $
274c3df794SDoug Rabson  */
284c3df794SDoug Rabson 
294c3df794SDoug Rabson #include <sys/param.h>
304c3df794SDoug Rabson #include <sys/kernel.h>
314c3df794SDoug Rabson #include <sys/systm.h>
324c3df794SDoug Rabson #include <sys/malloc.h>
334c3df794SDoug Rabson #include <sys/sysproto.h>
344c3df794SDoug Rabson #include <sys/sysent.h>
354c3df794SDoug Rabson #include <sys/syscall.h>
364c3df794SDoug Rabson #include <sys/module.h>
374c3df794SDoug Rabson #include <sys/linker.h>
384c3df794SDoug Rabson #include <sys/proc.h>
394c3df794SDoug Rabson 
4046db4836SPeter Wemm /*
4146db4836SPeter Wemm  * Acts like "nosys" but can be identified in sysent for dynamic call
4246db4836SPeter Wemm  * number assignment for a limited number of calls.
4346db4836SPeter Wemm  *
4446db4836SPeter Wemm  * Place holder for system call slots reserved for loadable modules.
4546db4836SPeter Wemm  */
4646db4836SPeter Wemm int
4746db4836SPeter Wemm lkmnosys(struct proc *p, struct nosys_args *args)
4846db4836SPeter Wemm {
4946db4836SPeter Wemm 	return(nosys(p, args));
5046db4836SPeter Wemm }
5146db4836SPeter Wemm 
524c3df794SDoug Rabson int
534c3df794SDoug Rabson syscall_register(int *offset, struct sysent *new_sysent,
544c3df794SDoug Rabson 		 struct sysent *old_sysent)
554c3df794SDoug Rabson {
564c3df794SDoug Rabson        if (*offset == NO_SYSCALL) {
574c3df794SDoug Rabson                int i;
584c3df794SDoug Rabson 
594c3df794SDoug Rabson                for (i = 1; i < SYS_MAXSYSCALL; ++i)
604c3df794SDoug Rabson                        if (sysent[i].sy_call == (sy_call_t *)lkmnosys)
614c3df794SDoug Rabson                                break;
624c3df794SDoug Rabson                if (i == SYS_MAXSYSCALL)
634c3df794SDoug Rabson                        return ENFILE;
644c3df794SDoug Rabson                *offset = i;
654c3df794SDoug Rabson        } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL)
664c3df794SDoug Rabson                return EINVAL;
674c3df794SDoug Rabson        else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys)
684c3df794SDoug Rabson                return EEXIST;
694c3df794SDoug Rabson 
704c3df794SDoug Rabson        *old_sysent = sysent[*offset];
714c3df794SDoug Rabson        sysent[*offset] = *new_sysent;
724c3df794SDoug Rabson        return 0;
734c3df794SDoug Rabson }
744c3df794SDoug Rabson 
754c3df794SDoug Rabson int
764c3df794SDoug Rabson syscall_deregister(int *offset, struct sysent *old_sysent)
774c3df794SDoug Rabson {
784c3df794SDoug Rabson        if (*offset)
794c3df794SDoug Rabson                sysent[*offset] = *old_sysent;
804c3df794SDoug Rabson        return 0;
814c3df794SDoug Rabson }
824c3df794SDoug Rabson 
834c3df794SDoug Rabson int
844c3df794SDoug Rabson syscall_module_handler(struct module *mod, int what, void *arg)
854c3df794SDoug Rabson {
864c3df794SDoug Rabson        struct syscall_module_data *data = (struct syscall_module_data*)arg;
87a35261efSDoug Rabson        modspecific_t ms;
884c3df794SDoug Rabson        int error;
894c3df794SDoug Rabson 
904c3df794SDoug Rabson        switch (what) {
914c3df794SDoug Rabson        case MOD_LOAD :
924c3df794SDoug Rabson                error = syscall_register(data->offset, data->new_sysent,
934c3df794SDoug Rabson                                         &data->old_sysent);
944c3df794SDoug Rabson                if (error)
954c3df794SDoug Rabson                        return error;
96a35261efSDoug Rabson 	       ms.intval = *data->offset;
97a35261efSDoug Rabson 	       module_setspecific(mod, &ms);
984c3df794SDoug Rabson                break;
994c3df794SDoug Rabson        case MOD_UNLOAD :
1004c3df794SDoug Rabson                error = syscall_deregister(data->offset, &data->old_sysent);
1014c3df794SDoug Rabson                if (error)
1024c3df794SDoug Rabson                        return error;
1034c3df794SDoug Rabson                break;
1044c3df794SDoug Rabson        }
1054c3df794SDoug Rabson        if (data->chainevh)
1064c3df794SDoug Rabson                return data->chainevh(mod, what, data->chainarg);
1074c3df794SDoug Rabson        else
1084c3df794SDoug Rabson                return 0;
1094c3df794SDoug Rabson }
110