diff options
author | 2014-10-09 04:05:04 +0000 | |
---|---|---|
committer | 2014-10-09 04:05:04 +0000 | |
commit | 220b89e12cc303dd98bc1e137625c658bd11e812 (patch) | |
tree | e6bd9820092533ee8b33430e015e1fc19aa8657c | |
parent | no need for lkm (diff) | |
download | wireguard-openbsd-220b89e12cc303dd98bc1e137625c658bd11e812.tar.xz wireguard-openbsd-220b89e12cc303dd98bc1e137625c658bd11e812.zip |
remove lkm files
-rw-r--r-- | sys/kern/kern_lkm.c | 918 | ||||
-rw-r--r-- | sys/sys/lkm.h | 365 |
2 files changed, 0 insertions, 1283 deletions
diff --git a/sys/kern/kern_lkm.c b/sys/kern/kern_lkm.c deleted file mode 100644 index 388b616a9e7..00000000000 --- a/sys/kern/kern_lkm.c +++ /dev/null @@ -1,918 +0,0 @@ -/* $OpenBSD: kern_lkm.c,v 1.49 2014/09/14 14:17:25 jsg Exp $ */ -/* $NetBSD: kern_lkm.c,v 1.31 1996/03/31 21:40:27 christos Exp $ */ - -/* - * Copyright (c) 1994 Christopher G. Demetriou - * Copyright (c) 1992 Terrence R. Lambert. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Terrence R. Lambert. - * 4. The name Terrence R. Lambert may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * XXX it's not really safe to unload *any* of the types which are - * currently loadable; e.g. you could unload a syscall which was being - * blocked in, etc. In the long term, a solution should be come up - * with, but "not right now." -- cgd - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/uio.h> -#include <sys/kernel.h> -#include <sys/vnode.h> -#include <sys/malloc.h> -#include <sys/mount.h> -#include <sys/exec.h> -#include <sys/syscallargs.h> -#include <sys/conf.h> - -#include <sys/lkm.h> -#include <sys/syscall.h> - -#include <uvm/uvm_extern.h> - -#ifdef DDB -#include <machine/db_machdep.h> -#include <ddb/db_sym.h> -#endif - -/* flags */ -#define LKM_ALLOC 0x01 -#define LKM_WANT 0x02 -#define LKM_INIT 0x04 - -#define LKMS_IDLE 0x00 -#define LKMS_RESERVED 0x01 -#define LKMS_LOADING 0x02 -#define LKMS_LOADING_SYMS 0x03 -#define LKMS_LOADED 0x04 -#define LKMS_UNLOADING 0x08 - -struct vm_map *lkm_map = NULL; - -static int lkm_v = 0; -static int lkm_state = LKMS_IDLE; - -static TAILQ_HEAD(lkmods, lkm_table) lkmods; /* table of loaded modules */ -static struct lkm_table *curp; /* global for in-progress ops */ - -static struct lkm_table *lkmalloc(void); -static void lkmfree(struct lkm_table *); -static struct lkm_table *lkmlookup(int, char *, int *); -static void lkmunreserve(void); -static int _lkm_syscall(struct lkm_table *, int); -static int _lkm_vfs(struct lkm_table *, int); -static int _lkm_dev(struct lkm_table *, int); -static int _lkm_exec(struct lkm_table *, int); - -void lkminit(void); -int lkmexists(struct lkm_table *); - -void init_exec(void); - -void -lkminit(void) -{ - - /* - * If machine-dependent code hasn't initialized the lkm_map - * then just use kernel_map. - */ - if (lkm_map == NULL) - lkm_map = kernel_map; - TAILQ_INIT(&lkmods); - lkm_v |= LKM_INIT; -} - -/*ARGSUSED*/ -int -lkmopen(dev_t dev, int flag, int devtype, struct proc *p) -{ - int error; - - if (minor(dev) != 0) - return (ENXIO); - - if (!(lkm_v & LKM_INIT)) - lkminit(); - - /* - * Use of the loadable kernel module device must be exclusive; we - * may try to remove this restriction later, but it's really no - * hardship. - */ - while (lkm_v & LKM_ALLOC) { - if (flag & FNONBLOCK) /* don't hang */ - return (EBUSY); - lkm_v |= LKM_WANT; - /* - * Sleep pending unlock; we use tsleep() to allow - * an alarm out of the open. - */ - error = tsleep(&lkm_v, TTIPRI|PCATCH, "lkmopn", 0); - if (error) - return (error); /* leave LKM_WANT set -- no problem */ - } - lkm_v |= LKM_ALLOC; - - return (0); /* pseudo-device open */ -} - -/* - * Allocates new LKM table entry, fills module id, inserts into the list. - * Returns NULL on failure. - * - */ -static struct lkm_table * -lkmalloc(void) -{ - struct lkm_table *p, *ret = NULL; - int id = 0; - - ret = malloc(sizeof(*ret), M_DEVBUF, M_WAITOK); - ret->refcnt = ret->depcnt = 0; - ret->sym_id = -1; - /* - * walk the list finding the first free id. as long as the list is - * kept sorted this is not too inefficient, which is why we insert in - * order below. - */ - TAILQ_FOREACH(p, &lkmods, list) { - if (id == p->id) - id++; - else - break; - } - ret->id = id; - if (p == NULL) /* either first or last entry */ - TAILQ_INSERT_TAIL(&lkmods, ret, list); - else - TAILQ_INSERT_BEFORE(p, ret, list); - - return ret; -} - -/* - * Frees the slot, decreases the number of modules. - */ -static void -lkmfree(struct lkm_table *p) -{ - - TAILQ_REMOVE(&lkmods, p, list); - free(p, M_DEVBUF, 0); - curp = NULL; -} - -struct lkm_table * -lkm_list(struct lkm_table *p) -{ - - if (p == NULL) - p = TAILQ_FIRST(&lkmods); - else - p = TAILQ_NEXT(p, list); - - return (p); -} - -static struct lkm_table * -lkmlookup(int i, char *name, int *error) -{ - struct lkm_table *p = NULL; - char istr[MAXLKMNAME]; - - /* - * p being NULL here implies the list is empty, so any lookup is - * invalid (name based or otherwise). Since the list of modules is - * kept sorted by id, lowest to highest, the id of the last entry - * will be the highest in use. - */ - p = TAILQ_LAST(&lkmods, lkmods); - if (p == NULL || i > p->id) { - *error = EINVAL; - return NULL; - } - - if (i < 0) { /* unload by name */ - /* - * Copy name and lookup id from all loaded - * modules. May fail. - */ - *error = copyinstr(name, istr, MAXLKMNAME-1, NULL); - if (*error) - return NULL; - istr[MAXLKMNAME-1] = '\0'; - - TAILQ_FOREACH(p, &lkmods, list) { - if (!strcmp(istr, p->private.lkm_any->lkm_name)) - break; - } - } else - TAILQ_FOREACH(p, &lkmods, list) - if (i == p->id) - break; - - if (p == NULL) - *error = ENOENT; - - return p; -} - -/* - * Unreserve the memory associated with the current loaded module; done on - * a coerced close of the lkm device (close on premature exit of modload) - * or explicitly by modload as a result of a link failure. - */ -static void -lkmunreserve(void) -{ - - if (lkm_state == LKMS_IDLE) - return; - -#ifdef DDB - if (curp && curp->sym_id != -1) - db_del_symbol_table(curp->private.lkm_any->lkm_name); -#endif - - if (curp && curp->syms) { - uvm_km_free(lkm_map, (vaddr_t)curp->syms, curp->sym_size); - curp->syms = NULL; - } - - /* - * Actually unreserve the memory - */ - if (curp && curp->area) { - uvm_km_free(lkm_map, curp->area, curp->size); - curp->area = 0; - } - lkm_state = LKMS_IDLE; -} - -int -lkmclose(dev_t dev, int flag, int mode, struct proc *p) -{ - - if (minor(dev) != 0) - return (ENXIO); - - if (!(lkm_v & LKM_ALLOC)) - return (EBADF); - - /* do this before waking the herd... */ - if (curp != NULL && !curp->refcnt) { - /* - * If we close before setting used, we have aborted - * by way of error or by way of close-on-exit from - * a premature exit of "modload". - */ - lkmunreserve(); - lkmfree(curp); - } - lkm_v &= ~LKM_ALLOC; - wakeup(&lkm_v); /* thundering herd "problem" here */ - - return (0); -} - -/*ARGSUSED*/ -int -lkmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) -{ - int error = 0; - - if (securelevel > 0) { - switch (cmd) { - case LMSTAT: - break; - default: - return (EPERM); - } - } - - if (!(flags & FWRITE)) { - switch (cmd) { - case LMSTAT: - break; - default: - return (EACCES); - } - } - - switch (cmd) { - case LMRESERV: - case LMRESERV_O: { - struct lmc_resrv *resrvp = (struct lmc_resrv *)data; - - if ((curp = lkmalloc()) == NULL) { - error = ENOMEM; - break; - } - curp->ver = (cmd == LMRESERV) ? LKM_VERSION : LKM_OLDVERSION; - resrvp->slot = curp->id; /* return slot */ - - /* - * Get memory for module - */ - curp->size = resrvp->size; - curp->area = uvm_km_zalloc(lkm_map, curp->size); - curp->offset = 0; - resrvp->addr = curp->area; - - if (cmd == LMRESERV && resrvp->sym_size) { - curp->sym_size = resrvp->sym_size; - curp->sym_symsize = resrvp->sym_symsize; - curp->syms = (caddr_t)uvm_km_zalloc(lkm_map, - curp->sym_size); - curp->sym_offset = 0; - resrvp->sym_addr = curp->syms; - } else { - curp->sym_size = 0; - curp->syms = 0; - curp->sym_offset = 0; - if (cmd == LMRESERV) - resrvp->sym_addr = 0; - } -#ifdef LKM_DEBUG - printf("LKM: LMRESERV (actual = 0x%08lx)\n", curp->area); - printf("LKM: LMRESERV (syms = 0x%08x)\n", curp->syms); - printf("LKM: LMRESERV (adjusted = 0x%08lx)\n", - trunc_page(curp->area)); -#endif /* LKM_DEBUG */ - - lkm_state = LKMS_RESERVED; - break; - } - - case LMLOADBUF: { - struct lmc_loadbuf *loadbufp = (struct lmc_loadbuf *)data; - - if ((lkm_state != LKMS_RESERVED && lkm_state != LKMS_LOADING) - || loadbufp->cnt < 0 - || loadbufp->cnt > MODIOBUF - || loadbufp->cnt > (curp->size - curp->offset)) { - error = ENOMEM; - break; - } - - /* copy in buffer full of data */ - error = copyin(loadbufp->data, - (caddr_t)curp->area + curp->offset, loadbufp->cnt); - if (error) - break; - - if ((curp->offset + loadbufp->cnt) < curp->size) - lkm_state = LKMS_LOADING; - else - lkm_state = LKMS_LOADING_SYMS; - - curp->offset += loadbufp->cnt; - break; - } - - case LMLOADSYMS: { - struct lmc_loadbuf *loadbufp = (struct lmc_loadbuf *)data; - - if ((lkm_state != LKMS_LOADING && - lkm_state != LKMS_LOADING_SYMS) - || loadbufp->cnt < 0 - || loadbufp->cnt > MODIOBUF - || loadbufp->cnt > (curp->sym_size - curp->sym_offset)) { - error = ENOMEM; - break; - } - - /* copy in buffer full of data*/ - error = copyin(loadbufp->data, curp->syms + - curp->sym_offset, loadbufp->cnt); - if (error) - break; - - if ((curp->sym_offset + loadbufp->cnt) < curp->sym_size) - lkm_state = LKMS_LOADING_SYMS; - else - lkm_state = LKMS_LOADED; - - curp->sym_offset += loadbufp->cnt; - break; - } - - case LMUNRESRV: - lkmunreserve(); - if (curp) - lkmfree(curp); - break; - - case LMREADY: - switch (lkm_state) { - case LKMS_LOADED: - break; - case LKMS_LOADING: - case LKMS_LOADING_SYMS: - if ((curp->size - curp->offset) > 0) - /* The remainder must be bss, so we clear it */ - memset((caddr_t)curp->area + curp->offset, 0, - curp->size - curp->offset); - break; - default: - return (ENXIO); - } - - curp->entry = (int (*)(struct lkm_table *, int, int)) - (*((long *) (data))); - -#ifdef LKM_DEBUG - printf("LKM: call entrypoint %x\n", curp->entry); -#endif /* LKM_DEBUG */ - - /* call entry(load)... (assigns "private" portion) */ - error = (*(curp->entry))(curp, LKM_E_LOAD, curp->ver); - if (error) { - /* - * Module may refuse loading or may have a - * version mismatch... - */ - lkm_state = LKMS_UNLOADING; /* for lkmunreserve */ - lkmunreserve(); /* free memory */ - lkmfree(curp); /* free slot */ - break; - } - -#ifdef LKM_DEBUG - printf("LKM: LMREADY, id=%d, dev=%d\n", curp->id, - curp->private.lkm_any->lkm_offset); -#endif /* LKM_DEBUG */ - -#ifdef DDB - if (curp->syms && curp->sym_offset >= curp->sym_size) { - curp->sym_id = db_add_symbol_table(curp->syms, - curp->syms + curp->sym_symsize, - curp->private.lkm_any->lkm_name, - curp->syms); - printf("DDB symbols added: %ld bytes\n", - curp->sym_symsize); - } -#endif /* DDB */ - - curp->refcnt++; - lkm_state = LKMS_IDLE; - break; - - case LMUNLOAD: { - struct lmc_unload *unloadp = (struct lmc_unload *)data; - - curp = lkmlookup(unloadp->id, unloadp->name, &error); - if (curp == NULL) - break; - - /* call entry(unload) */ - if ((*(curp->entry))(curp, LKM_E_UNLOAD, curp->ver)) { - error = EBUSY; - break; - } - - lkm_state = LKMS_UNLOADING; /* non-idle for lkmunreserve */ - lkmunreserve(); /* free memory */ - lkmfree(curp); /* free slot */ - break; - } - - case LMSTAT: { - struct lmc_stat *statp = (struct lmc_stat *)data; - - if ((curp = lkmlookup(statp->id, statp->name, &error)) == NULL) - break; - - if ((error = (*curp->entry)(curp, LKM_E_STAT, curp->ver))) - break; - - /* - * Copy out stat information for this module... - */ - statp->id = curp->id; - statp->offset = curp->private.lkm_any->lkm_offset; - statp->type = curp->private.lkm_any->lkm_type; - statp->area = curp->area; - statp->size = curp->size / PAGE_SIZE; - statp->private = (unsigned long)curp->private.lkm_any; - statp->ver = curp->private.lkm_any->lkm_ver; - copyoutstr(curp->private.lkm_any->lkm_name, - statp->name, MAXLKMNAME, NULL); - - break; - } - - default: - error = ENODEV; - break; - } - - return (error); -} - -/* - * Acts like "nosys" but can be identified in sysent for dynamic call - * number assignment for a limited number of calls. - * - * Place holder for system call slots reserved for loadable modules. - */ -int -sys_lkmnosys(struct proc *p, void *v, register_t *retval) -{ - - return (sys_nosys(p, v, retval)); -} - -/* - * Acts like "enodev", but can be identified in cdevsw and bdevsw for - * dynamic driver major number assignment for a limited number of - * drivers. - * - * Place holder for device switch slots reserved for loadable modules. - */ -int -lkmenodev(void) -{ - - return (enodev()); -} - -/* - * A placeholder function for load/unload/stat calls; simply returns zero. - * Used where people don't want to specify a special function. - */ -int -lkm_nofunc(struct lkm_table *lkmtp, int cmd) -{ - - return (0); -} - -int -lkmexists(struct lkm_table *lkmtp) -{ - struct lkm_table *p; - - TAILQ_FOREACH(p, &lkmods, list) { - if (!strcmp(lkmtp->private.lkm_any->lkm_name, - p->private.lkm_any->lkm_name) && p->refcnt) - return (1); - } - return (0); -} - -/* - * For the loadable system call described by the structure pointed to - * by lkmtp, load/unload/stat it depending on the cmd requested. - */ -static int -_lkm_syscall(struct lkm_table *lkmtp, int cmd) -{ - struct lkm_syscall *args = lkmtp->private.lkm_syscall; - int i; - int error = 0; - - switch (cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - if ((i = args->lkm_offset) == -1) { /* auto */ - /* - * Search the table looking for a slot... - */ - for (i = 0; i < SYS_MAXSYSCALL; i++) - if (sysent[i].sy_call == sys_lkmnosys) - break; /* found it! */ - /* out of allocable slots? */ - if (i == SYS_MAXSYSCALL) { - error = ENFILE; - break; - } - } else { /* assign */ - if (i < 0 || i >= SYS_MAXSYSCALL) { - error = EINVAL; - break; - } - } - - /* save old */ - bcopy(&sysent[i], &args->lkm_oldent, sizeof(struct sysent)); - - /* replace with new */ - bcopy(args->lkm_sysent, &sysent[i], sizeof(struct sysent)); - - /* done! */ - args->lkm_offset = i; /* slot in sysent[] */ - - break; - - case LKM_E_UNLOAD: - /* current slot... */ - i = args->lkm_offset; - - /* replace current slot contents with old contents */ - bcopy(&args->lkm_oldent, &sysent[i], sizeof(struct sysent)); - - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} - -/* - * For the loadable virtual file system described by the structure pointed - * to by lkmtp, load/unload/stat it depending on the cmd requested. - */ -static int -_lkm_vfs(struct lkm_table *lkmtp, int cmd) -{ - int error = 0; - struct lkm_vfs *args = lkmtp->private.lkm_vfs; - - switch (cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - error = vfs_register(args->lkm_vfsconf); - break; - - case LKM_E_UNLOAD: - error = vfs_unregister(args->lkm_vfsconf); - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} - -/* - * For the loadable device driver described by the structure pointed to - * by lkmtp, load/unload/stat it depending on the cmd requested. - */ -static int -_lkm_dev(struct lkm_table *lkmtp, int cmd) -{ - struct lkm_dev *args = lkmtp->private.lkm_dev; - int i; - int error = 0; - - switch (cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - switch (args->lkm_devtype) { - case LM_DT_BLOCK: - if ((i = args->lkm_offset) == -1) { /* auto */ - /* - * Search the table looking for a slot... - */ - for (i = 0; i < nblkdev; i++) - if (bdevsw[i].d_open == - (dev_type_open((*))) lkmenodev) - break; /* found it! */ - /* out of allocable slots? */ - if (i == nblkdev) { - error = ENFILE; - break; - } - } else { /* assign */ - if (i < 0 || i >= nblkdev) { - error = EINVAL; - break; - } - } - - /* save old */ - bcopy(&bdevsw[i], &args->lkm_olddev.bdev, - sizeof(struct bdevsw)); - - /* replace with new */ - bcopy(args->lkm_dev.bdev, &bdevsw[i], - sizeof(struct bdevsw)); - - /* done! */ - args->lkm_offset = i; /* slot in bdevsw[] */ - break; - - case LM_DT_CHAR: - if ((i = args->lkm_offset) == -1) { /* auto */ - /* - * Search the table looking for a slot... - */ - for (i = 0; i < nchrdev; i++) - if (cdevsw[i].d_open == - (dev_type_open((*))) lkmenodev) - break; /* found it! */ - /* out of allocable slots? */ - if (i == nchrdev) { - error = ENFILE; - break; - } - } else { /* assign */ - if (i < 0 || i >= nchrdev) { - error = EINVAL; - break; - } - } - - /* save old */ - bcopy(&cdevsw[i], &args->lkm_olddev.cdev, - sizeof(struct cdevsw)); - - /* replace with new */ - bcopy(args->lkm_dev.cdev, &cdevsw[i], - sizeof(struct cdevsw)); - - /* done! */ - args->lkm_offset = i; /* slot in cdevsw[] */ - - break; - - default: - error = ENODEV; - break; - } - break; - - case LKM_E_UNLOAD: - /* current slot... */ - i = args->lkm_offset; - - switch (args->lkm_devtype) { - case LM_DT_BLOCK: - /* replace current slot contents with old contents */ - bcopy(&args->lkm_olddev.bdev, &bdevsw[i], - sizeof(struct bdevsw)); - break; - - case LM_DT_CHAR: - /* replace current slot contents with old contents */ - bcopy(&args->lkm_olddev.cdev, &cdevsw[i], - sizeof(struct cdevsw)); - break; - - default: - error = ENODEV; - break; - } - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} - -/* - * For the loadable execution class described by the structure pointed to - * by lkmtp, load/unload/stat it depending on the cmd requested. - */ -static int -_lkm_exec(struct lkm_table *lkmtp, int cmd) -{ - struct lkm_exec *args = lkmtp->private.lkm_exec; - int i; - int error = 0; - - switch (cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - if ((i = args->lkm_offset) == -1) { /* auto */ - /* - * Search the table looking for a slot... - */ - for (i = 0; i < nexecs; i++) - if (execsw[i].es_check == NULL) - break; /* found it! */ - /* out of allocable slots? */ - if (i == nexecs) { - error = ENFILE; - break; - } - } else { /* assign */ - if (i < 0 || i >= nexecs) { - error = EINVAL; - break; - } - } - - /* save old */ - bcopy(&execsw[i], &args->lkm_oldexec, sizeof(struct execsw)); - - /* replace with new */ - bcopy(args->lkm_exec, &execsw[i], sizeof(struct execsw)); - - /* need to recompute max header size */ - init_exec(); - - /* done! */ - args->lkm_offset = i; /* slot in execsw[] */ - - break; - - case LKM_E_UNLOAD: - /* current slot... */ - i = args->lkm_offset; - - /* replace current slot contents with old contents */ - bcopy(&args->lkm_oldexec, &execsw[i], sizeof(struct execsw)); - - /* need to recompute max header size */ - init_exec(); - - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} - -/* - * This code handles the per-module type "wiring-in" of loadable modules - * into existing kernel tables. For "LM_MISC" modules, wiring and unwiring - * is assumed to be done in their entry routines internal to the module - * itself. - */ -int -lkmdispatch(struct lkm_table *lkmtp, int cmd) -{ - int error = 0; - -#ifdef LKM_DEBUG - printf("lkmdispatch: %x %d\n", lkmtp, cmd); -#endif /* LKM_DEBUG */ - - switch (lkmtp->private.lkm_any->lkm_type) { - case LM_SYSCALL: - error = _lkm_syscall(lkmtp, cmd); - break; - - case LM_VFS: - error = _lkm_vfs(lkmtp, cmd); - break; - - case LM_DEV: - error = _lkm_dev(lkmtp, cmd); - break; - - case LM_EXEC: - error = _lkm_exec(lkmtp, cmd); - break; - - case LM_MISC: /* ignore content -- no "misc-specific" procedure */ - break; - - default: - error = ENXIO; /* unknown type */ - break; - } - - return (error); -} diff --git a/sys/sys/lkm.h b/sys/sys/lkm.h deleted file mode 100644 index 15023091ca7..00000000000 --- a/sys/sys/lkm.h +++ /dev/null @@ -1,365 +0,0 @@ -/* $OpenBSD: lkm.h,v 1.13 2008/11/07 02:23:04 deraadt Exp $ */ -/* $NetBSD: lkm.h,v 1.12 1996/02/09 18:25:13 christos Exp $ */ - -/* - * Header file used by loadable kernel modules and loadable kernel module - * utilities. - * - * 23 Jan 93 Terry Lambert Original - * - * Copyright (c) 1996 Michael Shalayeff - * Copyright (c) 1992 Terrence R. Lambert. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Terrence R. Lambert. - * 4. The name Terrence R. Lambert may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY TERRENCE R. LAMBERT ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _SYS_LKM_H_ -#define _SYS_LKM_H_ - -#include <sys/queue.h> - -/* - * Supported module types - */ -typedef enum loadmod { - LM_SYSCALL, - LM_VFS, - LM_DEV, - LM_EXEC, - LM_MISC -} MODTYPE; - - -#define LKM_OLDVERSION 1 /* version of module loader */ -#define LKM_VERSION 2 /* version of module loader */ -#define MAXLKMNAME 32 - -/****************************************************************************/ - -#ifdef _KERNEL - -/* - * Loadable system call - */ -struct lkm_syscall { - MODTYPE lkm_type; - int lkm_ver; - char *lkm_name; - u_long lkm_offset; /* save/assign area */ - struct sysent *lkm_sysent; - struct sysent lkm_oldent; /* save area for unload */ -}; - -/* - * Loadable file system - */ -struct lkm_vfs { - MODTYPE lkm_type; - int lkm_ver; - char *lkm_name; - u_long lkm_offset; - struct vfsconf *lkm_vfsconf; -}; - -/* - * Supported device module types - */ -typedef enum devtype { - LM_DT_BLOCK, - LM_DT_CHAR -} DEVTYPE; - -/* - * Loadable device driver - */ -struct lkm_dev { - MODTYPE lkm_type; - int lkm_ver; - char *lkm_name; - u_long lkm_offset; - DEVTYPE lkm_devtype; - union { - void *anon; - struct bdevsw *bdev; - struct cdevsw *cdev; - } lkm_dev; - union { - struct bdevsw bdev; - struct cdevsw cdev; - } lkm_olddev; -}; - -/* - * Exec loader - */ -struct lkm_exec { - MODTYPE lkm_type; - int lkm_ver; - char *lkm_name; - u_long lkm_offset; - struct execsw *lkm_exec; - struct execsw lkm_oldexec; -}; - -/* - * Miscellaneous module (complex load/unload, potentially complex stat - */ -struct lkm_misc { - MODTYPE lkm_type; - int lkm_ver; - char *lkm_name; - u_long lkm_offset; -}; - -/* - * Any module (to get type and name info without knowing type) - */ -struct lkm_any { - MODTYPE lkm_type; - int lkm_ver; - char *lkm_name; - u_long lkm_offset; -}; - - -/* - * Generic reference ala XEvent to allow single entry point in the xxxinit() - * routine. - */ -union lkm_generic { - struct lkm_any *lkm_any; - struct lkm_syscall *lkm_syscall; - struct lkm_vfs *lkm_vfs; - struct lkm_dev *lkm_dev; - struct lkm_exec *lkm_exec; - struct lkm_misc *lkm_misc; -}; - -/* - * Per module information structure - */ -struct lkm_table { - TAILQ_ENTRY(lkm_table) list; - int type; - u_long size; - u_long offset; - u_long area; - - int ver; /* version (INIT) */ - int refcnt; /* reference count (INIT) */ - int depcnt; /* dependency count (INIT) */ - int id; /* identifier (INIT) */ - - int (*entry)(struct lkm_table *, int, int); /* entry function */ - union lkm_generic private; /* module private data */ - - /* ddb support */ - char *syms; /* ? start of symbol table */ - u_long sym_size; /* ? size of symbol table */ - u_long sym_offset; /* ? offset */ - u_long sym_symsize; /* ? symsize */ - char *sym_addr; /* ? addr */ - int sym_id; /* ? symtab id from ddb */ -}; - - -#define LKM_E_LOAD 1 -#define LKM_E_UNLOAD 2 -#define LKM_E_STAT 3 - - -#define MOD_SYSCALL(name,callslot,sysentp) \ - static struct lkm_syscall _module = { \ - LM_SYSCALL, \ - LKM_VERSION, \ - name, \ - callslot, \ - sysentp \ - }; - -#define MOD_VFS(name,vfsslot,vfsconf) \ - static struct lkm_vfs _module = { \ - LM_VFS, \ - LKM_VERSION, \ - name, \ - vfsslot, \ - vfsconf \ - }; - -#define MOD_DEV(name,devtype,devslot,devp) \ - static struct lkm_dev _module = { \ - LM_DEV, \ - LKM_VERSION, \ - name, \ - devslot, \ - devtype, \ - {(void *)devp} \ - }; - -#define MOD_EXEC(name,execslot,execsw) \ - static struct lkm_exec _module = { \ - LM_EXEC, \ - LKM_VERSION, \ - name, \ - execslot, \ - execsw \ - }; - -#define MOD_MISC(name) \ - static struct lkm_misc _module = { \ - LM_MISC, \ - LKM_VERSION, \ - name \ - }; - - -extern int lkm_nofunc(struct lkm_table *lkmtp, int cmd); -extern struct lkm_table *lkm_list(struct lkm_table *); -extern int lkmdispatch(struct lkm_table *, int); - -/* - * DISPATCH -- body function for use in module entry point function; - * generally, the function body will consist entirely of a single - * DISPATCH line. - * - * If load/unload/stat are called on each corresponding entry instance. - * If no function is desired for load/stat/unload, lkm_nofunc() should - * be specified. "cmd" is passed to each function so that a single - * function can be used if desired. - */ -#define DISPATCH(lkmtp,cmd,ver,load,unload,stat) do { \ - if (ver != LKM_VERSION) \ - return EINVAL; /* version mismatch */ \ - switch (cmd) { \ - int error; \ - case LKM_E_LOAD: \ - lkmtp->private.lkm_any = (struct lkm_any *)&_module; \ - if ((error = load(lkmtp, cmd)) != 0) \ - return error; \ - break; \ - case LKM_E_UNLOAD: \ - if ((error = unload(lkmtp, cmd)) != 0) \ - return error; \ - break; \ - case LKM_E_STAT: \ - if ((error = stat(lkmtp, cmd)) != 0) \ - return error; \ - break; \ - } \ - return lkmdispatch(lkmtp, cmd); \ -} while (/* CONSTCOND */ 0) - -extern struct vm_map *lkm_map; - -#endif /* _KERNEL */ - -/****************************************************************************/ - -/* - * IOCTL's recognized by /dev/lkm - */ -#define LMRESERV_O _IOWR('K', 0, struct lmc_resrv) -#define LMLOADBUF _IOW('K', 1, struct lmc_loadbuf) -#define LMUNRESRV _IO('K', 2) -#define LMREADY _IOW('K', 3, u_long) -#define LMRESERV _IOWR('K', 4, struct lmc_resrv) - -#define LMLOAD _IOW('K', 9, struct lmc_load) -#define LMUNLOAD _IOWR('K', 10, struct lmc_unload) -#define LMSTAT _IOWR('K', 11, struct lmc_stat) -#define LMLOADSYMS _IOW('K', 12, struct lmc_loadbuf) - -#define MODIOBUF 512 /* # of bytes at a time to loadbuf */ - -/* - * IOCTL arguments - */ - - -/* - * Reserve a page-aligned block of kernel memory for the module - */ -struct lmc_resrv { - u_long size; /* IN: size of module to reserve */ - char *name; /* IN: name (must be provided */ - int slot; /* OUT: allocated slot (module ID) */ - u_long addr; /* OUT: Link-to address */ - /* ddb support */ - char *syms; /* ? start of symbol table */ - u_long sym_size; /* ? size of symbol table */ - u_long sym_offset; /* ? offset */ - u_long sym_symsize; /* ? symsize */ - char *sym_addr; /* ? addr */ -}; - - -/* - * Copy a buffer at a time into the allocated area in the kernel; writes - * are assumed to occur contiguously. - */ -struct lmc_loadbuf { - int cnt; /* IN: # of chars pointed to by data */ - char *data; /* IN: pointer to data buffer */ -}; - - -/* - * Load a module (assumes it's been mmapped to address before call) - */ -struct lmc_load { - caddr_t address; /* IN: user space mmap address */ - int status; /* OUT: status of operation */ - int id; /* OUT: module ID if loaded */ -}; - -/* - * Unload a module (by name/id) - */ -struct lmc_unload { - int id; /* IN: module ID to unload */ - char *name; /* IN: module name to unload if id -1 */ - int status; /* OUT: status of operation */ -}; - - -/* - * Get module information for a given id (or name if id == -1). - */ -struct lmc_stat { - int id; /* IN: module ID to unload */ - char *name; /* IN/OUT: name of module */ - u_long offset; /* OUT: target table offset */ - MODTYPE type; /* OUT: type of module */ - u_long area; /* OUT: kernel load addr */ - u_long size; /* OUT: module size (pages) */ - u_long private; /* OUT: module private data */ - int ver; /* OUT: lkm compile version */ -}; - -#endif /* !_SYS_LKM_H_ */ |