diff options
| author | ad <ad@NetBSD.org> | 2008-11-12 12:35:50 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2008-11-12 12:35:50 +0000 |
| commit | 0efea177e37295fed654875d875160c47500d6bd (patch) | |
| tree | 9d0589344a5d07b9a511a2e81ebbd701744d03b5 /sys/kern | |
| parent | 0f81d3e0a26c2833cd085c472a4a77c325486b75 (diff) | |
Remove LKMs and switch to the module framework, pass 1.
Proposed on tech-kern@.
Diffstat (limited to 'sys/kern')
| -rw-r--r-- | sys/kern/init_main.c | 7 | ||||
| -rw-r--r-- | sys/kern/init_sysent.c | 47 | ||||
| -rw-r--r-- | sys/kern/kern_exec.c | 56 | ||||
| -rw-r--r-- | sys/kern/kern_ksyms.c | 264 | ||||
| -rw-r--r-- | sys/kern/kern_lkm.c | 1159 | ||||
| -rw-r--r-- | sys/kern/kern_lock.c | 6 | ||||
| -rw-r--r-- | sys/kern/kern_module.c | 20 | ||||
| -rw-r--r-- | sys/kern/kern_sysctl.c | 6 | ||||
| -rw-r--r-- | sys/kern/subr_autoconf.c | 6 | ||||
| -rw-r--r-- | sys/kern/subr_kobj.c | 23 | ||||
| -rw-r--r-- | sys/kern/syscalls.c | 37 | ||||
| -rw-r--r-- | sys/kern/syscalls.master | 35 | ||||
| -rw-r--r-- | sys/kern/uipc_accf.c | 35 | ||||
| -rw-r--r-- | sys/kern/vfs_syscalls.c | 5 | ||||
| -rw-r--r-- | sys/kern/vfs_vnops.c | 9 |
15 files changed, 83 insertions, 1632 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 558b8fab4f9..7744a015a22 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.371 2008/10/28 15:33:10 tsutsui Exp $ */ +/* $NetBSD: init_main.c,v 1.372 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.371 2008/10/28 15:33:10 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.372 2008/11/12 12:36:16 ad Exp $"); #include "opt_ddb.h" #include "opt_ipsec.h" @@ -186,9 +186,6 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.371 2008/10/28 15:33:10 tsutsui Exp #include <sys/rnd.h> #endif #include <sys/pipe.h> -#ifdef LKM -#include <sys/lkm.h> -#endif #if NVERIEXEC > 0 #include <sys/verified_exec.h> #endif /* NVERIEXEC > 0 */ diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 224cae469fc..1ab785f7a55 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_sysent.c,v 1.229 2008/10/16 20:12:23 wrstuden Exp $ */ +/* $NetBSD: init_sysent.c,v 1.230 2008/11/12 12:36:16 ad Exp $ */ /* * System call switch table. @@ -8,7 +8,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_sysent.c,v 1.229 2008/10/16 20:12:23 wrstuden Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_sysent.c,v 1.230 2008/11/12 12:36:16 ad Exp $"); #include "opt_nfsserver.h" #include "opt_ntp.h" @@ -579,49 +579,26 @@ struct sysent sysent[] = { (sy_call_t *)sys_reboot }, /* 208 = reboot */ { ns(struct sys_poll_args), 0, (sy_call_t *)sys_poll }, /* 209 = poll */ -#if defined(LKM) || !defined(_KERNEL) { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 210 = lkmnosys */ + sys_nosys }, /* 210 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 211 = lkmnosys */ + sys_nosys }, /* 211 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 212 = lkmnosys */ + sys_nosys }, /* 212 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 213 = lkmnosys */ + sys_nosys }, /* 213 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 214 = lkmnosys */ + sys_nosys }, /* 214 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 215 = lkmnosys */ + sys_nosys }, /* 215 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 216 = lkmnosys */ + sys_nosys }, /* 216 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 217 = lkmnosys */ + sys_nosys }, /* 217 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 218 = lkmnosys */ + sys_nosys }, /* 218 = unimplemented */ { 0, 0, 0, - (sy_call_t *)sys_lkmnosys }, /* 219 = lkmnosys */ -#else /* !LKM */ - { 0, 0, 0, - sys_nosys }, /* 210 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 211 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 212 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 213 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 214 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 215 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 216 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 217 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 218 = excluded lkmnosys */ - { 0, 0, 0, - sys_nosys }, /* 219 = excluded lkmnosys */ -#endif /* !LKM */ + sys_nosys }, /* 219 = unimplemented */ #if defined(SYSVSEM) || !defined(_KERNEL) { ns(struct compat_14_sys___semctl_args), 0, (sy_call_t *)compat_14(sys___semctl) },/* 220 = compat_14___semctl */ diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 41ec0c6265a..43f90179dca 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.280 2008/10/21 20:52:11 matt Exp $ */ +/* $NetBSD: kern_exec.c,v 1.281 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -59,7 +59,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.280 2008/10/21 20:52:11 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.281 2008/11/12 12:36:16 ad Exp $"); #include "opt_ktrace.h" #include "opt_syscall_debug.h" @@ -132,7 +132,6 @@ static int nexecs; u_int exec_maxhdrsz; /* must not be static - netbsd32 needs it */ -#ifdef LKM /* list of supported emulations */ static LIST_HEAD(emlist_head, emul_entry) el_head = LIST_HEAD_INITIALIZER(el_head); @@ -155,7 +154,6 @@ struct execsw_entry { struct execsw_entry *next; const struct execsw *es; }; -#endif /* LKM */ #ifdef SYSCALL_DEBUG extern const char * const syscallnames[]; @@ -236,7 +234,6 @@ const struct emul emul_netbsd = { startlwp, }; -#ifdef LKM /* * Exec lock. Used to control access to execsw[] structures. * This must not be static so that netbsd32 can access it, too. @@ -244,7 +241,6 @@ const struct emul emul_netbsd = { krwlock_t exec_lock; static void link_es(struct execsw_entry **, const struct execsw *); -#endif /* LKM */ static kmutex_t sigobject_lock; @@ -572,9 +568,7 @@ execve1(struct lwp *l, const char *path, char * const *args, pack.ep_esch = NULL; pack.ep_pax_flags = 0; -#ifdef LKM rw_enter(&exec_lock, RW_READER); -#endif /* see if we can run it. */ if ((error = check_exec(l, &pack)) != 0) { @@ -1091,9 +1085,7 @@ execve1(struct lwp *l, const char *path, char * const *args, /* Allow new references from the debugger/procfs. */ rw_exit(&p->p_reflock); -#ifdef LKM rw_exit(&exec_lock); -#endif mutex_enter(proc_lock); @@ -1149,9 +1141,7 @@ execve1(struct lwp *l, const char *path, char * const *args, if (pack.ep_interp != NULL) vrele(pack.ep_interp); -#ifdef LKM rw_exit(&exec_lock); -#endif clrflg: lwp_lock(l); @@ -1165,9 +1155,7 @@ execve1(struct lwp *l, const char *path, char * const *args, exec_abort: PNBUF_PUT(pathbuf); rw_exit(&p->p_reflock); -#ifdef LKM rw_exit(&exec_lock); -#endif /* * the old process doesn't exist anymore. exit gracefully. @@ -1240,7 +1228,6 @@ copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, return 0; } -#ifdef LKM /* * Find an emulation of given name in list of emulations. * Needs to be called with the exec_lock held. @@ -1556,45 +1543,6 @@ exec_init(int init_boot) return 0; } -#endif - -#ifndef LKM -/* - * Simplified exec_init() for kernels without LKMs. Only initialize - * exec_maxhdrsz and execsw[]. - */ -int -exec_init(int init_boot) -{ - int i; - -#ifdef DIAGNOSTIC - if (!init_boot) - panic("exec_init(): called with init_boot == 0"); -#endif - - /* do one-time initializations */ - nexecs = nexecs_builtin; - execsw = kmem_alloc(nexecs * sizeof(struct execsw *), KM_SLEEP); - - pool_init(&exec_pool, NCARGS, 0, 0, PR_NOALIGN|PR_NOTOUCH, - "execargs", &exec_palloc, IPL_NONE); - pool_sethardlimit(&exec_pool, maxexec, "should not happen", 0); - - /* - * Fill in execsw[] and figure out the maximum size of an exec header. - */ - exec_maxhdrsz = 0; - for(i=0; i < nexecs; i++) { - execsw[i] = &execsw_builtin[i]; - if (execsw_builtin[i].es_hdrsz > exec_maxhdrsz) - exec_maxhdrsz = execsw_builtin[i].es_hdrsz; - } - - return 0; - -} -#endif /* !LKM */ static int exec_sigcode_map(struct proc *p, const struct emul *e) diff --git a/sys/kern/kern_ksyms.c b/sys/kern/kern_ksyms.c index d3b1461ef28..b6e09a9f47e 100644 --- a/sys/kern/kern_ksyms.c +++ b/sys/kern/kern_ksyms.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_ksyms.c,v 1.41 2008/10/24 13:55:42 christos Exp $ */ +/* $NetBSD: kern_ksyms.c,v 1.42 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.41 2008/10/24 13:55:42 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.42 2008/11/12 12:36:16 ad Exp $"); #ifdef _KERNEL #include "opt_ddb.h" @@ -316,6 +316,7 @@ findsym(const char *name, struct ksyms_symtab *table) void ksymsattach(int arg) { + if (baseidx == 0) ptree_gen(0, &kernel_symtab); } @@ -351,7 +352,6 @@ addsymtab(const char *name, void *symstart, size_t symsize, tab->sd_maxsym = NULL; tab->sd_usroffset = 0; tab->sd_gone = false; - tab->sd_malloc = false; /* XXXLKM */ #ifdef KSYMS_DEBUG printf("newstart %p sym %p ksyms_symsz %d str %p strsz %d send %p\n", newstart, symstart, symsize, strstart, strsize, @@ -488,6 +488,8 @@ ksyms_init_explicit(void *ehdr, void *symstart, size_t symsize, void *strstart, size_t strsize) { + mutex_init(&ksyms_lock, MUTEX_DEFAULT, IPL_NONE); + if (!ksyms_verify(symstart, strstart)) return; @@ -507,7 +509,7 @@ ksyms_init_explicit(void *ehdr, void *symstart, size_t symsize, */ int ksyms_getval_unlocked(const char *mod, const char *sym, unsigned long *val, - int type) + int type) { struct ksyms_symtab *st; Elf_Sym *es; @@ -554,7 +556,6 @@ ksyms_getval(const char *mod, const char *sym, unsigned long *val, int type) return rc; } - /* * Get "mod" and "symbol" associated with an address. * Returns 0 if success or ENOENT if no such entry. @@ -616,252 +617,6 @@ ksyms_getname(const char **mod, const char **sym, vaddr_t v, int f) } /* - * Temporary work structure for dynamic loaded symbol tables. - * - * XXX REMOVE WHEN LKMS GO. - */ -struct syminfo { - size_t cursyms; - size_t curnamep; - size_t maxsyms; - size_t maxnamep; - Elf_Sym *syms; - char *symnames; -}; - -/* - * Add a symbol to the temporary save area for symbols. - * - * XXX REMOVE WHEN LKMS GO. - */ -static void -addsym(struct syminfo *info, const Elf_Sym *sym, const char *name, - const char *mod) -{ - int len, mlen; - -#ifdef KSYMS_DEBUG - if (ksyms_debug & FOLLOW_MORE_CALLS) - printf("addsym: name %s val %lx\n", name, (long)sym->st_value); -#endif - len = strlen(name) + 1; - if (mod) - mlen = 1 + strlen(mod); - else - mlen = 0; - if (info->cursyms == info->maxsyms || - (len + mlen + info->curnamep) > info->maxnamep) { - printf("addsym: too many symbols, skipping '%s'\n", name); - return; - } - strlcpy(&info->symnames[info->curnamep], name, - info->maxnamep - info->curnamep); - if (mlen) { - info->symnames[info->curnamep + len - 1] = '.'; - strlcpy(&info->symnames[info->curnamep + len], mod, - info->maxnamep - (info->curnamep + len)); - len += mlen; - } - info->syms[info->cursyms] = *sym; - info->syms[info->cursyms].st_name = info->curnamep; - info->curnamep += len; - if (len > ksyms_maxlen) - ksyms_maxlen = len; - info->cursyms++; -} - -/* - * XXX REMOVE WHEN LKMS GO. - */ -static int -specialsym(const char *symname) -{ - - return !strcmp(symname, "_bss_start") || - !strcmp(symname, "__bss_start") || - !strcmp(symname, "_bss_end__") || - !strcmp(symname, "__bss_end__") || - !strcmp(symname, "_edata") || - !strcmp(symname, "_end") || - !strcmp(symname, "__end") || - !strcmp(symname, "__end__") || - !strncmp(symname, "__start_link_set_", 17) || - !strncmp(symname, "__stop_link_set_", 16); -} - -/* - * Adds a symbol table. - * "name" is the module name, "start" and "size" is where the symbol table - * is located, and "type" is in which binary format the symbol table is. - * New memory for keeping the symbol table is allocated in this function. - * Returns 0 if success and EEXIST if the module name is in use. - * - * XXX REMOVE WHEN LKMS GO. - */ -int -ksyms_addsymtab(const char *mod, void *symstart, vsize_t symsize, - char *strstart, vsize_t strsize) -{ - Elf_Sym *sym = symstart; - struct ksyms_symtab *st; - unsigned long rval; - int i; - char *name; - struct syminfo info; - -#ifdef KSYMS_DEBUG - if (ksyms_debug & FOLLOW_CALLS) - printf("ksyms_addsymtab: mod %s symsize %lx strsize %lx\n", - mod, symsize, strsize); -#endif - - mutex_enter(&ksyms_lock); - - /* Check if this symtab already loaded */ - TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { - if (st->sd_gone) - continue; - if (strcmp(mod, st->sd_name) == 0) { - mutex_exit(&ksyms_lock); - return EEXIST; - } - } - - /* - * XXX - Only add a symbol if it do not exist already. - * This is because of a flaw in the current LKM implementation, - * these loops will be removed once the in-kernel linker is in place. - */ - memset(&info, 0, sizeof(info)); - for (i = 0; i < symsize/sizeof(Elf_Sym); i++) { - char * const symname = strstart + sym[i].st_name; - if (sym[i].st_name == 0) - continue; /* Just ignore */ - - /* check validity of the symbol */ - /* XXX - save local symbols if DDB */ - if (ELF_ST_BIND(sym[i].st_info) != STB_GLOBAL) - continue; - - /* Check if the symbol exists */ - if (ksyms_getval_unlocked(NULL, symname, &rval, KSYMS_EXTERN) - == 0) { - /* Check (and complain) about differing values */ - if (sym[i].st_value != rval && - sym[i].st_shndx != SHN_UNDEF) { - if (specialsym(symname)) { - info.maxsyms++; - info.maxnamep += strlen(symname) + 1 + - strlen(mod) + 1; - } else { - printf("%s: symbol '%s' redeclared with" - " different value (%lx != %lx)\n", - mod, symname, - rval, (long)sym[i].st_value); - } - } - } else { - /* - * Count this symbol - */ - info.maxsyms++; - info.maxnamep += strlen(symname) + 1; - } - } - - /* - * Now that we know the sizes, malloc the structures. - */ - info.syms = malloc(sizeof(Elf_Sym)*info.maxsyms, M_DEVBUF, M_WAITOK); - info.symnames = malloc(info.maxnamep, M_DEVBUF, M_WAITOK); - - /* - * Now that we have the symbols, actually fill in the structures. - */ - for (i = 0; i < symsize/sizeof(Elf_Sym); i++) { - char * const symname = strstart + sym[i].st_name; - if (sym[i].st_name == 0) - continue; /* Just ignore */ - - /* check validity of the symbol */ - /* XXX - save local symbols if DDB */ - if (ELF_ST_BIND(sym[i].st_info) != STB_GLOBAL) - continue; - - /* Check if the symbol exists */ - if (ksyms_getval_unlocked(NULL, symname, &rval, KSYMS_EXTERN) - == 0) { - if ((sym[i].st_value != rval) && specialsym(symname)) { - addsym(&info, &sym[i], symname, mod); - } - } else - /* Ok, save this symbol */ - addsym(&info, &sym[i], symname, NULL); - } - - st = kmem_zalloc(sizeof(*st), KM_SLEEP); - i = strlen(mod) + 1; - name = malloc(i, M_DEVBUF, M_WAITOK); - strlcpy(name, mod, i); - st->sd_name = name; - st->sd_symstart = info.syms; - st->sd_symsize = sizeof(Elf_Sym)*info.maxsyms; - st->sd_strstart = info.symnames; - st->sd_strsize = info.maxnamep; - st->sd_malloc = true; - - /* Make them absolute references */ - sym = st->sd_symstart; - for (i = 0; i < st->sd_symsize/sizeof(Elf_Sym); i++) - sym[i].st_shndx = SHN_ABS; - - /* ksymsread() is unlocked, so membar. */ - membar_producer(); - TAILQ_INSERT_TAIL(&ksyms_symtabs, st, sd_queue); - ksyms_sizes_calc(); - mutex_exit(&ksyms_lock); - - return 0; -} - -/* - * Remove a symbol table specified by name. - * Returns 0 if success, EBUSY if device open and ENOENT if no such name. - * - * XXX REMOVE WHEN LKMS GO. - */ -int -ksyms_delsymtab(const char *mod) -{ - struct ksyms_symtab *st; - - mutex_enter(&ksyms_lock); - TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) { - if (st->sd_gone) - continue; - if (strcmp(mod, st->sd_name) != 0) - continue; - if (ksyms_isopen) { - st->sd_gone = true; - mutex_exit(&ksyms_lock); - return 0; - } - TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue); - ksyms_sizes_calc(); - mutex_exit(&ksyms_lock); - KASSERT(st->sd_malloc); - free(st->sd_symstart, M_DEVBUF); - free(st->sd_strstart, M_DEVBUF); - /* XXXUNCONST LINTED - const castaway */ - free(__UNCONST(st->sd_name), M_DEVBUF); - kmem_free(st, sizeof(*st)); - return 0; - } - mutex_exit(&ksyms_lock); - return ENOENT; -} - -/* * Add a symbol table from a loadable module. */ void @@ -890,7 +645,6 @@ ksyms_modunload(const char *name) continue; if (strcmp(name, st->sd_name) != 0) continue; - KASSERT(!st->sd_malloc); /* XXXLKM */ st->sd_gone = true; if (!ksyms_isopen) { TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue); @@ -1091,12 +845,6 @@ ksymsclose(dev_t dev, int oflags, int devtype, struct lwp *l) if (st->sd_gone) { TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue); kmem_free(st, sizeof(*st)); - if (st->sd_malloc) { /* XXXLKM */ - free(st->sd_symstart, M_DEVBUF); - free(st->sd_strstart, M_DEVBUF); - /* XXXUNCONST LINTED - const castaway */ - free(__UNCONST(st->sd_name), M_DEVBUF); - } resize = true; } } diff --git a/sys/kern/kern_lkm.c b/sys/kern/kern_lkm.c deleted file mode 100644 index a004e2df17b..00000000000 --- a/sys/kern/kern_lkm.c +++ /dev/null @@ -1,1159 +0,0 @@ -/* $NetBSD: kern_lkm.c,v 1.98 2007/12/20 23:03:08 dsl 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/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_lkm.c,v 1.98 2007/12/20 23:03:08 dsl Exp $"); - -#include "opt_ddb.h" -#include "opt_malloclog.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/ioctl.h> -#include <sys/tty.h> -#include <sys/file.h> -#include <sys/proc.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/ksyms.h> -#include <sys/device.h> -#include <sys/once.h> -#include <sys/kauth.h> - -#include <sys/lkm.h> -#include <sys/syscall.h> -#ifdef DDB -#include <machine/db_machdep.h> -#include <ddb/db_sym.h> -#endif - -#include <uvm/uvm_extern.h> - -struct vm_map *lkm_map; - -#define LKM_SPACE_ALLOC(size, exec) \ - uvm_km_alloc(lkm_map, (size), 0, \ - UVM_KMF_WIRED | ((exec) ? UVM_KMF_EXEC : 0)) -#define LKM_SPACE_FREE(addr, size) \ - uvm_km_free(lkm_map, (addr), (size), UVM_KMF_WIRED) - -#if !defined(DEBUG) && defined(LKMDEBUG) -# define DEBUG -#endif - -#ifdef DEBUG -# define LKMDB_INFO 0x01 -# define LKMDB_LOAD 0x02 -int lkmdebug = 0; -#endif - -#define LKM_ALLOC 0x01 - -#define LKMS_IDLE 0x00 -#define LKMS_RESERVED 0x01 -#define LKMS_LOADING 0x02 -#define LKMS_UNLOADING 0x08 - -static int lkm_v = 0; -static int lkm_state = LKMS_IDLE; - -static TAILQ_HEAD(lkms_head, lkm_table) lkmods = /* table of loaded modules */ - TAILQ_HEAD_INITIALIZER(lkmods); -static struct lkm_table *curp; /* global for in-progress ops */ - -static struct lkm_table *lkmlookup(int, char *, int, int *); -static struct lkm_table *lkmalloc(void); -static void lkmfree(void); -static void lkmunreserve(int); -static int _lkm_syscall(struct lkm_table *, int); -static int _lkm_vfs(struct lkm_table *, int); -static int _lkm_dev(struct lkm_table *, int); -#ifdef STREAMS -static int _lkm_strmod(struct lkm_table *, int); -#endif -static int _lkm_exec(struct lkm_table *, int); -static int _lkm_compat(struct lkm_table *, int); -static int _lkm_drv(struct lkm_table *, int); - -static int _lkm_checkver(struct lkm_table *); - -dev_type_open(lkmopen); -dev_type_close(lkmclose); -dev_type_ioctl(lkmioctl); - -const struct cdevsw lkm_cdevsw = { - lkmopen, lkmclose, noread, nowrite, lkmioctl, - nostop, notty, nopoll, nommap, nokqfilter, D_OTHER, -}; - -static ONCE_DECL(lkm_init_once); - -static int -lkm_init(void) -{ - /* - * If machine-dependent code hasn't initialized the lkm_map - * then just use kernel_map. - */ - if (lkm_map == NULL) - lkm_map = kernel_map; - - return 0; -} - -/*ARGSUSED*/ -int -lkmopen(dev_t dev, int flag, int devtype, struct lwp *l) -{ - int error; - - RUN_ONCE(&lkm_init_once, lkm_init); - - if (minor(dev) != 0) - return (ENXIO); /* bad minor # */ - - /* - * 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); - /* - * Sleep pending unlock; we use tsleep() to allow - * an alarm out of the open. - */ - error = tsleep((void *)&lkm_v, TTIPRI|PCATCH, "lkmopn", 0); - if (error) - return (error); - } - lkm_v |= LKM_ALLOC; - - return (0); /* pseudo-device open */ -} - -/* - * Look up for a LKM in the list. - */ -static struct lkm_table * -lkmlookup(int i, char *name, int need_copyin, int *error) -{ - struct lkm_table *p; - 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, lkms_head); - 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. - */ - if (need_copyin) { - *error = copyinstr(name, istr, MAXLKMNAME - 1, NULL); - if (*error) - return (NULL); - } else - strncpy(istr, name, MAXLKMNAME - 1); - istr[MAXLKMNAME - 1] = '\0'; - - TAILQ_FOREACH(p, &lkmods, link) { - if (strcmp(istr, p->private.lkm_any->lkm_name) == 0) - break; - } - } else - TAILQ_FOREACH(p, &lkmods, link) - if (i == p->id) - break; - - if (p == NULL) - *error = ENOENT; - - return (p); -} - -/* - * Allocates memory for a new LKM table entry and inserts in the list. - * Returns NULL on failure. - */ -static struct lkm_table * -lkmalloc(void) -{ - struct lkm_table *p, *ret; - int id = 0; - - ret = malloc(sizeof(struct lkm_table), M_DEVBUF, M_NOWAIT); - if (ret == NULL) - return (NULL); - ret->refcnt = 0; - ret->forced = 0; - - /* find the first unused id */ - TAILQ_FOREACH(p, &lkmods, link) { - if (id != p->id) - break; - id++; - } - ret->id = id; - - if (p == NULL) - TAILQ_INSERT_TAIL(&lkmods, ret, link); - else - TAILQ_INSERT_BEFORE(p, ret, link); - - return (ret); -} - -/* - * Frees the current LKM table entry. - */ -static void -lkmfree(void) -{ - TAILQ_REMOVE(&lkmods, curp, link); - free(curp, M_DEVBUF); - curp = NULL; -} - -/* - * 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(int delsymtab) -{ - - if (lkm_state == LKMS_IDLE) - return; - - if (curp && curp->syms) { - if (delsymtab) - ksyms_delsymtab(curp->private.lkm_any->lkm_name); - LKM_SPACE_FREE(curp->syms, curp->sym_size); - curp->syms = 0; - } - /* - * Actually unreserve the memory - */ - if (curp && curp->area) { - LKM_SPACE_FREE(curp->area, curp->size); - curp->area = 0; - } - - if (curp && curp->forced) - curp->forced = 0; - - lkm_state = LKMS_IDLE; -} - -int -lkmclose(dev_t dev, int flag, int mode, struct lwp *l) -{ - - if (!(lkm_v & LKM_ALLOC)) { -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) - printf("LKM: close before open!\n"); -#endif /* DEBUG */ - return (EBADF); - } - - /* do this before waking the herd... */ - if (curp != NULL && curp->refcnt == 0) { - /* - * 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(1); /* coerce state to LKM_IDLE */ - lkmfree(); - } - - lkm_v &= ~LKM_ALLOC; - wakeup((void *)&lkm_v); /* thundering herd "problem" here */ - - return (0); /* pseudo-device closed */ -} - -/*ARGSUSED*/ -int -lkmioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) -{ - int i, error = 0; - struct lmc_resrv *resrvp; - struct lmc_loadbuf *loadbufp; - struct lmc_unload *unloadp; - struct lmc_stat *statp; - - switch(cmd) { - case LMRESERV: /* reserve pages for a module */ - if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LKM, - 0, (void *)cmd, NULL, NULL)) - return EPERM; - - if ((flag & FWRITE) == 0) /* only allow this if writing */ - return EPERM; - - resrvp = (struct lmc_resrv *)data; - - curp = lkmalloc(); - if (curp == NULL) { - error = ENOMEM; - break; - } - resrvp->slot = curp->id; /* return slot */ - - /* - * Get memory for module - */ - curp->size = resrvp->size; - curp->area = LKM_SPACE_ALLOC(curp->size, 1); - curp->offset = 0; /* load offset */ - - resrvp->addr = curp->area; /* ret kernel addr */ - - if (resrvp->sym_size) { - curp->sym_size = resrvp->sym_size; - curp->sym_symsize = resrvp->sym_symsize; - curp->syms = (u_long)LKM_SPACE_ALLOC(curp->sym_size, 0); - curp->sym_offset = 0; - resrvp->sym_addr = curp->syms; /* ret symbol addr */ - } else { - curp->sym_size = 0; - curp->syms = 0; - curp->sym_offset = 0; - resrvp->sym_addr = 0; - } - -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) { - printf("LKM: LMRESERV (actual = 0x%08lx)\n", - curp->area); - printf("LKM: LMRESERV (syms = 0x%08lx)\n", - curp->syms); - printf("LKM: LMRESERV (adjusted = 0x%08lx)\n", - trunc_page(curp->area)); - } -#endif /* DEBUG */ - lkm_state = LKMS_RESERVED; - break; - - case LMLOADBUF: /* Copy in; stateful, follows LMRESERV */ - if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LKM, - 0, (void *)cmd, NULL, NULL)) - return EPERM; - - if ((flag & FWRITE) == 0) /* only allow this if writing */ - return EPERM; - - loadbufp = (struct lmc_loadbuf *)data; - i = loadbufp->cnt; - if ((lkm_state != LKMS_RESERVED && lkm_state != LKMS_LOADING) - || i < 0 - || i > MODIOBUF - || i > curp->size - curp->offset) { - error = ENOMEM; - break; - } - - /* copy in buffer full of data */ - error = copyin(loadbufp->data, - (char *)curp->area + curp->offset, i); - if (error) - break; - -#ifdef PMAP_NEED_PROCWR - pmap_procwr(&proc0, curp->area + curp->offset, i); -#endif - if ((curp->offset + i) < curp->size) { - lkm_state = LKMS_LOADING; -#ifdef DEBUG - if (lkmdebug & LKMDB_LOAD) - printf("LKM: LMLOADBUF (loading @ %ld of %ld, i = %d)\n", - curp->offset, curp->size, i); -#endif /* DEBUG */ - } - curp->offset += i; - break; - - case LMLOADSYMS: /* Copy in; stateful, follows LMRESERV*/ - if ((flag & FWRITE) == 0) /* only allow this if writing */ - return EPERM; - - loadbufp = (struct lmc_loadbuf *)data; - i = loadbufp->cnt; - if ((lkm_state != LKMS_LOADING) - || i < 0 - || i > MODIOBUF - || i > curp->sym_size - curp->sym_offset) { - error = ENOMEM; - break; - } - - /* copy in buffer full of data*/ - if ((error = copyin(loadbufp->data, - (char *)(curp->syms) + curp->sym_offset, - i)) != 0) - break; - - if ((curp->sym_offset + i) < curp->sym_size) { - lkm_state = LKMS_LOADING; -#ifdef DEBUG - if (lkmdebug & LKMDB_LOAD) - printf( "LKM: LMLOADSYMS (loading @ %ld of %ld, i = %d)\n", - curp->sym_offset, curp->sym_size, i); -#endif /* DEBUG*/ - } - curp->sym_offset += i; - break; - - case LMUNRESRV: /* discard reserved pages for a module */ - if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LKM, - 0, (void *)cmd, NULL, NULL)) - return EPERM; - - if ((flag & FWRITE) == 0) /* only allow this if writing */ - return EPERM; - - lkmunreserve(0); /* coerce state to LKM_IDLE */ - if (curp != NULL) - lkmfree(); -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) - printf("LKM: LMUNRESERV\n"); -#endif /* DEBUG */ - break; - - case LMREADY: /* module loaded: call entry */ - if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LKM, - 0, (void *)cmd, NULL, NULL)) - return EPERM; - - if ((flag & FWRITE) == 0) /* only allow this if writing */ - return EPERM; - - if (lkm_state != LKMS_LOADING) { -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) - printf("lkm_state is %02x\n", lkm_state); -#endif /* DEBUG */ - return ENXIO; - } - - if (curp->size - curp->offset > 0) { - /* The remainder must be bss, so we clear it */ - memset((char *)curp->area + curp->offset, 0, - curp->size - curp->offset); - } - -#ifdef DDB - /* - * Temporarily load the symbol table before the entry - * routine is called, so that the symbols are available - * for DDB backtrace and breakpoints. - */ - if (curp->syms && curp->sym_offset >= curp->sym_size) { - error = ksyms_addsymtab("/lkmtemp/", - (char *)curp->syms, curp->sym_symsize, - (char *)curp->syms + curp->sym_symsize, - curp->sym_size - curp->sym_symsize); - - if (error) - goto rdyfail; - -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) - printf( "DDB symbols added!\n" ); -#endif - } -#endif /* DDB */ - - curp->entry = (int (*)(struct lkm_table *, int, int)) - (*((long *) (data))); - - /* call entry(load)... (assigns "private" portion) */ - error = (*(curp->entry))(curp, LKM_E_LOAD, LKM_VERSION); - - if (curp->syms && curp->sym_offset >= curp->sym_size) { -#ifdef DDB - ksyms_delsymtab("/lkmtemp/"); -#endif - - if (!error) { - error = ksyms_addsymtab(curp->private.lkm_any->lkm_name, - (char *)curp->syms, curp->sym_symsize, - (char *)curp->syms + curp->sym_symsize, - curp->sym_size - curp->sym_symsize); - } - } - - if (error) { -#ifdef DDB - rdyfail: -#endif - /* - * Module may refuse loading or may have a - * version mismatch... - */ - lkm_state = LKMS_UNLOADING; /* for lkmunreserve */ - lkmunreserve(0); /* free memory */ - lkmfree(); /* free slot */ -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) - printf("lkm entry point failed with error %d\n", - error); -#endif /* DEBUG */ - break; - } - curp->refcnt++; - -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) - printf("LKM: LMREADY\n"); -#endif /* DEBUG */ - lkm_state = LKMS_IDLE; - break; - - case LMUNLOAD: /* unload a module */ - if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LKM, - 0, (void *)cmd, NULL, NULL)) - return EPERM; - - if ((flag & FWRITE) == 0) /* only allow this if writing */ - return EPERM; - - unloadp = (struct lmc_unload *)data; - - curp = lkmlookup(unloadp->id, unloadp->name, 1, &error); - if (curp == NULL) - break; - - /* call entry(unload) */ - if ((*(curp->entry))(curp, LKM_E_UNLOAD, LKM_VERSION)) { - error = EBUSY; - break; - } - - lkm_state = LKMS_UNLOADING; /* non-idle for lkmunreserve */ - lkmunreserve(1); /* free memory */ - lkmfree(); /* free slot */ - break; - - case LMSTAT: /* stat a module by id/name */ - /* allow readers and writers to stat */ - - statp = (struct lmc_stat *)data; - - if ((curp = lkmlookup(statp->id, statp->name, 0, &error)) == NULL) - break; - - if ((error = (*curp->entry)(curp, LKM_E_STAT, LKM_VERSION))) - 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 / 1024; - statp->private = (unsigned long)curp->private.lkm_any; - statp->ver = LKM_VERSION; - copystr(curp->private.lkm_any->lkm_name, - statp->name, - MAXLKMNAME - 2, - (size_t *)0); - - break; - -#ifdef LMFORCE - case LMFORCE: /* stateful, optionally follows LMRESERV */ - if (kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LKM, - 0, (void *)cmd, NULL, NULL)) - return EPERM; - - if ((flag & FWRITE) == 0) /* only allow this if writing */ - return EPERM; - - if (lkm_state != LKMS_RESERVED) { - error = EPERM; - break; - } - - curp->forced = (*(u_long *)data != 0); - break; -#endif /* LMFORCE */ - - default: /* bad ioctl()... */ - error = ENOTTY; - 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 lwp *l, const void *v, register_t *retval) -{ - - return (sys_nosys(l, v, retval)); -} - -/* - * 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; - - /* see if name exists... */ - TAILQ_FOREACH(p, &lkmods, link) { - if (strcmp(lkmtp->private.lkm_any->lkm_name, - p->private.lkm_any->lkm_name) == 0 && (p->refcnt != 0)) - return (1); /* already loaded... */ - } - - return (0); /* module not loaded... */ -} - -/* - * 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->mod.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 */ - memcpy(&args->lkm_oldent, &sysent[i], sizeof(struct sysent)); - - /* replace with new */ - memcpy(&sysent[i], args->lkm_sysent, sizeof(struct sysent)); - - /* done! */ - args->mod.lkm_offset = i; /* slot in sysent[] */ - - break; - - case LKM_E_UNLOAD: - /* current slot... */ - i = args->mod.lkm_offset; - - /* replace current slot contents with old contents */ - memcpy(&sysent[i], &args->lkm_oldent, 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) -{ - struct lkm_vfs *args = lkmtp->private.lkm_vfs; - int error = 0; - - switch(cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - /* Establish the file system. */ - if ((error = vfs_attach(args->lkm_vfsops)) != 0) - return (error); - - /* done! */ - break; - - case LKM_E_UNLOAD: - /* Disestablish the file system. */ - if ((error = vfs_detach(args->lkm_vfsops)) != 0) - return (error); - 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 error; - - switch(cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - error = devsw_attach(args->lkm_devname, - args->lkm_bdev, &args->lkm_bdevmaj, - args->lkm_cdev, &args->lkm_cdevmaj); - if (error != 0) - return (error); - - args->mod.lkm_offset = - LKM_MAKEMAJOR(args->lkm_bdevmaj, args->lkm_cdevmaj); - break; - - case LKM_E_UNLOAD: - devsw_detach(args->lkm_bdev, args->lkm_cdev); - args->lkm_bdevmaj = -1; - args->lkm_cdevmaj = -1; - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (0); -} - -#ifdef STREAMS -/* - * For the loadable streams module described by the structure pointed to - * by lkmtp, load/unload/stat it depending on the cmd requested. - */ -static int -_lkm_strmod(struct lkm_table *lkmtp, int cmd) -{ - struct lkm_strmod *args = lkmtp->private.lkm_strmod; - int i; - int error = 0; - - switch(cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - break; - - case LKM_E_UNLOAD: - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} -#endif /* STREAMS */ - -/* - * 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 error = 0; - - switch(cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - /* this would also fill in the emulation pointer in - * args->lkm_execsw */ - error = exec_add(args->lkm_execsw, args->lkm_emul); - break; - - case LKM_E_UNLOAD: - error = exec_remove(args->lkm_execsw); - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} - -/* - * For the loadable compat/emulation class described by the structure pointed to - * by lkmtp, load/unload/stat it depending on the cmd requested. - */ -static int -_lkm_compat(struct lkm_table *lkmtp, int cmd) -{ - struct lkm_compat *args = lkmtp->private.lkm_compat; - int error = 0; - - switch(cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - error = emul_register(args->lkm_compat, 0); - break; - - case LKM_E_UNLOAD: - error = emul_unregister(args->lkm_compat->e_name); - break; - - case LKM_E_STAT: /* no special handling... */ - break; - } - - return (error); -} - -static int -drvlkm_load(struct cfdriver **cd, const struct cfattachlkminit *cai, - struct cfdata *cf) -{ - const struct cfattachlkminit *cfai; - int i, error, j; - - for (i = 0; cd[i]; i++) { - error = config_cfdriver_attach(cd[i]); - if (!error) - continue; - if (error != EEXIST) { - printf("%s: unable to register driver\n", - cd[i]->cd_name); - /* XXX roll back previous attachments */ - goto out; - } - printf("driver %s already present\n", cd[i]->cd_name); - /* - * get existing drivers out of the list so we won't try - * to detach them - */ - for (j = i; cd[j]; j++) - cd[j] = cd[j + 1]; - i--; /* continue at same index */ - } - - for (cfai = cai; cfai->cfai_name; cfai++) { - for (i = 0; cfai->cfai_list[i]; i++) { - error = config_cfattach_attach(cfai->cfai_name, - cfai->cfai_list[i]); - if (!error) - continue; - if (error != EEXIST) { - printf("%s: unable to register cfattach\n", - cfai->cfai_list[i]->ca_name); - /* XXX roll back previous attachments */ - goto out; - } - printf("driver attachment %s for %s already present\n", - cfai->cfai_list[i]->ca_name, cfai->cfai_name); - /* - * get existing attachments out of the list so we - * won't try to detach them - */ - for (j = i; cfai->cfai_list[j]; j++) - cfai->cfai_list[j] = cfai->cfai_list[j + 1]; - i--; /* continue at same index */ - } - } - - error = config_cfdata_attach(cf, 1); - /* XXX roll back cfdriver / cfattach attachments in error case */ - -out: - return (error); -} - -static int -drvlkm_unload(struct cfdriver **cd, const struct cfattachlkminit *cai, - struct cfdata *cf) -{ - const struct cfattachlkminit *cfai; - int i, error; - - error = config_cfdata_detach(cf); - if (error) - return (error); - - for (cfai = cai; cfai->cfai_name; cfai++) { - for (i = 0; cfai->cfai_list[i]; i++) { - error = config_cfattach_detach(cfai->cfai_name, - cfai->cfai_list[i]); - if (error) { - printf("%s: unable to deregister cfattach\n", - cfai->cfai_list[i]->ca_name); - return (error); - } - } - } - - for (i = 0; cd[i]; i++) { - error = config_cfdriver_detach(cd[i]); - if (error) { - printf("%s: unable to deregister cfdriver\n", - cd[i]->cd_name); - return (error); - } - } - - return (0); -} - -static int -_lkm_drv(struct lkm_table *lkmtp, int cmd) -{ - struct lkm_drv *args = lkmtp->private.lkm_drv; - int error = 0; - - switch(cmd) { - case LKM_E_LOAD: - /* don't load twice! */ - if (lkmexists(lkmtp)) - return (EEXIST); - - error = drvlkm_load(args->lkm_cd, - args->lkm_cai, - args->lkm_cf); - break; - - case LKM_E_UNLOAD: - error = drvlkm_unload(args->lkm_cd, - args->lkm_cai, - args->lkm_cf); - 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; /* default = success */ -#ifdef DEBUG - if (lkmdebug & LKMDB_INFO) - printf( "lkmdispatch: %p %d\n", lkmtp, cmd ); -#endif - - /* If loading, check the LKM is compatible */ - if (cmd == LKM_E_LOAD) { - if (_lkm_checkver(lkmtp)) - return (EPROGMISMATCH); - } - - 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; - -#ifdef STREAMS - case LM_STRMOD: - { - struct lkm_strmod *args = lkmtp->private.lkm_strmod; - } - break; - -#endif /* STREAMS */ - - case LM_EXEC: - error = _lkm_exec(lkmtp, cmd); - break; - - case LM_COMPAT: - error = _lkm_compat(lkmtp, cmd); - break; - - case LM_MISC: /* ignore content -- no "misc-specific" procedure */ - break; - - case LM_DRV: - error = _lkm_drv(lkmtp, cmd); - break; - - default: - error = ENXIO; /* unknown type */ - break; - } - - return (error); -} - -/* - * Check LKM version against current kernel. - */ -static int -_lkm_checkver(struct lkm_table *lkmtp) -{ - struct lkm_any *mod = lkmtp->private.lkm_any; - - if (mod->lkm_modver != LKM_VERSION) { - printf("LKM '%s': LKM version mismatch - LKM %d, kernel %d\n", - mod->lkm_name, mod->lkm_modver, LKM_VERSION); - return (1); - } - - if (lkmtp->forced) { - printf("LKM '%s': forced load, skipping compatibility checks\n", - mod->lkm_name); - return (0); - } - - if (mod->lkm_sysver != __NetBSD_Version__) { - printf("LKM '%s': kernel version mismatch - LKM %d, kernel %d\n", - mod->lkm_name, mod->lkm_sysver, __NetBSD_Version__); - return (2); - } - - /* - * Following might eventually be changed to take into account envdep, - * if it's non-NULL. - */ - if (strcmp(mod->lkm_envver, _LKM_ENV_VERSION) != 0) { - const char *kenv = _LKM_ENV_VERSION; - const char *envver = mod->lkm_envver; - - if (kenv[0] == ',') - kenv++; - if (envver[0] == ',') - envver++; - - printf("LKM '%s': environment compile options mismatch - LKM '%s', kernel '%s'\n", - mod->lkm_name, envver, kenv); - return (3); - } - - /* - * Basic parameters match, LKM is hopefully compatible. - * Cross fingers and approve. - */ - return (0); -} diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 30fb4cb90d6..fa3f84a8cf6 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_lock.c,v 1.146 2008/07/02 14:47:34 matt Exp $ */ +/* $NetBSD: kern_lock.c,v 1.147 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.146 2008/07/02 14:47:34 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.147 2008/11/12 12:36:16 ad Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -55,7 +55,6 @@ bool kernel_lock_dodebug; __cpu_simple_lock_t kernel_lock[CACHE_LINE_SIZE / sizeof(__cpu_simple_lock_t)] __aligned(CACHE_LINE_SIZE); -#if defined(DEBUG) || defined(LKM) void assert_sleepable(void) { @@ -83,7 +82,6 @@ assert_sleepable(void) (void *)RETURN_ADDRESS); } } -#endif /* defined(DEBUG) || defined(LKM) */ /* * Functions for manipulating the kernel_lock. We put them here diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index a0def37ffbb..d334eb9f688 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -1,9 +1,12 @@ -/* $NetBSD: kern_module.c,v 1.24 2008/10/22 11:19:15 ad Exp $ */ +/* $NetBSD: kern_module.c,v 1.25 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. * + * This code is derived from software developed for The NetBSD Foundation + * by Andrew Doran. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -30,10 +33,8 @@ * Kernel module support. */ -#include "opt_modular.h" - #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.24 2008/10/22 11:19:15 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.25 2008/11/12 12:36:16 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -49,9 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.24 2008/10/22 11:19:15 ad Exp $"); #include <machine/stdarg.h> -#ifndef LKM /* XXX */ -struct vm_map *lkm_map; -#endif +struct vm_map *module_map; struct modlist module_list = TAILQ_HEAD_INITIALIZER(module_list); struct modlist module_bootlist = TAILQ_HEAD_INITIALIZER(module_bootlist); @@ -97,10 +96,11 @@ module_error(const char *fmt, ...) void module_init(void) { - extern struct vm_map *lkm_map; + extern struct vm_map *module_map; - if (lkm_map == NULL) - lkm_map = kernel_map; + if (module_map == NULL) { + module_map = kernel_map; + } mutex_init(&module_lock, MUTEX_DEFAULT, IPL_NONE); #ifdef MODULAR /* XXX */ module_init_md(); diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index d9ce9391f78..b381c04d662 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_sysctl.c,v 1.218 2008/10/23 20:41:14 christos Exp $ */ +/* $NetBSD: kern_sysctl.c,v 1.219 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2003, 2007, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.218 2008/10/23 20:41:14 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.219 2008/11/12 12:36:16 ad Exp $"); #include "opt_defcorename.h" #include "ksyms.h" @@ -1994,7 +1994,7 @@ sysctl_createv(struct sysctllog **log, int cflags, * initialize lock state -- we need locks if the main tree has * been marked as complete, but since we could be called from * either there, or from a device driver (say, at device - * insertion), or from an lkm (at lkm load time, say), we + * insertion), or from a module (at module load time, say), we * don't really want to "wait"... */ sysctl_lock(true); diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c index f9a87cd8016..202b0b463c1 100644 --- a/sys/kern/subr_autoconf.c +++ b/sys/kern/subr_autoconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.163 2008/09/07 22:36:36 cube Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.164 2008/11/12 12:36:16 ad Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.163 2008/09/07 22:36:36 cube Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.164 2008/11/12 12:36:16 ad Exp $"); #include "opt_ddb.h" #include "drvctl.h" @@ -800,7 +800,7 @@ rescan_with_cfdata(const struct cfdata *cf) /* - * "alldevs" is likely longer than an LKM's cfdata, so make it + * "alldevs" is likely longer than a modules's cfdata, so make it * the outer loop. */ for (d = deviter_first(&di, 0); d != NULL; d = deviter_next(&di)) { diff --git a/sys/kern/subr_kobj.c b/sys/kern/subr_kobj.c index 31a70be8414..ecb5b626226 100644 --- a/sys/kern/subr_kobj.c +++ b/sys/kern/subr_kobj.c @@ -1,9 +1,12 @@ -/* $NetBSD: subr_kobj.c,v 1.24 2008/10/20 20:07:35 ad Exp $ */ +/* $NetBSD: subr_kobj.c,v 1.25 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. * All rights reserved. * + * This code is derived from software developed for The NetBSD Foundation + * by Andrew Doran. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -59,10 +62,8 @@ * TODO: adjust kmem_alloc() calls to avoid needless fragmentation. */ -#include "opt_modular.h" - #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.24 2008/10/20 20:07:35 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.25 2008/11/12 12:36:16 ad Exp $"); #define ELFSIZE ARCH_ELFSIZE @@ -80,7 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.24 2008/10/20 20:07:35 ad Exp $"); #include <sys/vnode.h> #include <sys/fcntl.h> #include <sys/ksyms.h> -#include <sys/lkm.h> +#include <sys/module.h> #include <sys/exec.h> #include <sys/exec_elf.h> @@ -88,7 +89,6 @@ __KERNEL_RCSID(0, "$NetBSD: subr_kobj.c,v 1.24 2008/10/20 20:07:35 ad Exp $"); #include <uvm/uvm_extern.h> - typedef struct { void *addr; Elf_Off size; @@ -118,7 +118,7 @@ typedef enum kobjtype { } kobjtype_t; struct kobj { - char ko_name[MAXLKMNAME]; + char ko_name[MAXMODNAME]; kobjtype_t ko_type; void *ko_source; ssize_t ko_memsize; @@ -152,7 +152,7 @@ static void kobj_free(kobj_t, void *, size_t); static void kobj_close(kobj_t); static int kobj_load(kobj_t); -extern struct vm_map *lkm_map; +extern struct vm_map *module_map; /* * kobj_load_file: @@ -503,7 +503,7 @@ kobj_load(kobj_t ko) if (ko->ko_type == KT_MEMORY) { mapbase += (vaddr_t)ko->ko_source; } else { - mapbase = uvm_km_alloc(lkm_map, round_page(mapsize), + mapbase = uvm_km_alloc(module_map, round_page(mapsize), 0, UVM_KMF_WIRED | UVM_KMF_EXEC); if (mapbase == 0) { error = ENOMEM; @@ -674,7 +674,7 @@ kobj_unload(kobj_t ko) } } if (ko->ko_address != 0 && ko->ko_type != KT_MEMORY) { - uvm_km_free(lkm_map, ko->ko_address, round_page(ko->ko_size), + uvm_km_free(module_map, ko->ko_address, round_page(ko->ko_size), UVM_KMF_WIRED); } if (ko->ko_ksyms == true) { @@ -737,7 +737,8 @@ kobj_affix(kobj_t ko, const char *name) /* * Now that we know the name, register the symbol table. - * Do after global relocations because ksyms will pack it. + * Do after global relocations because ksyms will pack + * the table. */ ksyms_modload(ko->ko_name, ko->ko_symtab, ko->ko_symcnt * sizeof(Elf_Sym), ko->ko_strtab, ko->ko_strtabsz); diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index d39ab082b66..8032fcf244f 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: syscalls.c,v 1.220 2008/10/16 20:12:23 wrstuden Exp $ */ +/* $NetBSD: syscalls.c,v 1.221 2008/11/12 12:36:16 ad Exp $ */ /* * System call names. @@ -8,7 +8,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: syscalls.c,v 1.220 2008/10/16 20:12:23 wrstuden Exp $"); +__KERNEL_RCSID(0, "$NetBSD: syscalls.c,v 1.221 2008/11/12 12:36:16 ad Exp $"); #if defined(_KERNEL_OPT) #include "opt_nfsserver.h" @@ -277,29 +277,16 @@ const char *const syscallnames[] = { /* 207 */ "getpgid", /* 208 */ "reboot", /* 209 */ "poll", -#if defined(LKM) || !defined(_KERNEL) - /* 210 */ "lkmnosys", - /* 211 */ "lkmnosys", - /* 212 */ "lkmnosys", - /* 213 */ "lkmnosys", - /* 214 */ "lkmnosys", - /* 215 */ "lkmnosys", - /* 216 */ "lkmnosys", - /* 217 */ "lkmnosys", - /* 218 */ "lkmnosys", - /* 219 */ "lkmnosys", -#else /* !LKM */ - /* 210 */ "#210 (excluded lkmnosys)", - /* 211 */ "#211 (excluded lkmnosys)", - /* 212 */ "#212 (excluded lkmnosys)", - /* 213 */ "#213 (excluded lkmnosys)", - /* 214 */ "#214 (excluded lkmnosys)", - /* 215 */ "#215 (excluded lkmnosys)", - /* 216 */ "#216 (excluded lkmnosys)", - /* 217 */ "#217 (excluded lkmnosys)", - /* 218 */ "#218 (excluded lkmnosys)", - /* 219 */ "#219 (excluded lkmnosys)", -#endif /* !LKM */ + /* 210 */ "#210 (unimplemented)", + /* 211 */ "#211 (unimplemented)", + /* 212 */ "#212 (unimplemented)", + /* 213 */ "#213 (unimplemented)", + /* 214 */ "#214 (unimplemented)", + /* 215 */ "#215 (unimplemented)", + /* 216 */ "#216 (unimplemented)", + /* 217 */ "#217 (unimplemented)", + /* 218 */ "#218 (unimplemented)", + /* 219 */ "#219 (unimplemented)", #if defined(SYSVSEM) || !defined(_KERNEL) /* 220 */ "compat_14___semctl", /* 221 */ "semget", diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 5d1b251a71e..b81b61701d9 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.211 2008/10/16 19:30:49 pooka Exp $ + $NetBSD: syscalls.master,v 1.212 2008/11/12 12:36:16 ad Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -426,29 +426,16 @@ ; ; Syscalls 210-219 are reserved for dynamically loaded syscalls ; -#if defined(LKM) || !defined(_KERNEL) -210 NODEF { int sys_lkmnosys(void); } -211 NODEF { int sys_lkmnosys(void); } -212 NODEF { int sys_lkmnosys(void); } -213 NODEF { int sys_lkmnosys(void); } -214 NODEF { int sys_lkmnosys(void); } -215 NODEF { int sys_lkmnosys(void); } -216 NODEF { int sys_lkmnosys(void); } -217 NODEF { int sys_lkmnosys(void); } -218 NODEF { int sys_lkmnosys(void); } -219 NODEF { int sys_lkmnosys(void); } -#else /* !LKM */ -210 EXCL lkmnosys -211 EXCL lkmnosys -212 EXCL lkmnosys -213 EXCL lkmnosys -214 EXCL lkmnosys -215 EXCL lkmnosys -216 EXCL lkmnosys -217 EXCL lkmnosys -218 EXCL lkmnosys -219 EXCL lkmnosys -#endif /* !LKM */ +210 UNIMPL +211 UNIMPL +212 UNIMPL +213 UNIMPL +214 UNIMPL +215 UNIMPL +216 UNIMPL +217 UNIMPL +218 UNIMPL +219 UNIMPL ; System calls 220-300 are reserved for use by NetBSD #if defined(SYSVSEM) || !defined(_KERNEL) 220 COMPAT_14 { int sys___semctl(int semid, int semnum, int cmd, \ diff --git a/sys/kern/uipc_accf.c b/sys/kern/uipc_accf.c index 3ce0d54bfb2..5aa9501ca5d 100644 --- a/sys/kern/uipc_accf.c +++ b/sys/kern/uipc_accf.c @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_accf.c,v 1.6 2008/10/15 08:25:28 ad Exp $ */ +/* $NetBSD: uipc_accf.c,v 1.7 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_accf.c,v 1.6 2008/10/15 08:25:28 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_accf.c,v 1.7 2008/11/12 12:36:16 ad Exp $"); #define ACCEPT_FILTER_MOD @@ -69,7 +69,6 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_accf.c,v 1.6 2008/10/15 08:25:28 ad Exp $"); #include <sys/lock.h> #include <sys/kmem.h> #include <sys/mbuf.h> -#include <sys/lkm.h> #include <sys/rwlock.h> #include <sys/protosw.h> #include <sys/sysctl.h> @@ -113,6 +112,8 @@ accept_filt_add(struct accept_filter *filt) { struct accept_filter *p; + accept_filter_init(); + rw_enter(&accept_filter_lock, RW_WRITER); LIST_FOREACH(p, &accept_filtlsthd, accf_next) { if (strcmp(p->accf_name, filt->accf_name) == 0) { @@ -186,34 +187,6 @@ accept_filter_init(void) } int -accept_filt_generic_mod_event(struct lkm_table *lkmtp, int event, void *data) -{ - struct accept_filter *accfp = (struct accept_filter *) data; - int error; - - switch (event) { - case LKM_E_LOAD: - accept_filter_init(); - error = accept_filt_add(accfp); - break; - - case LKM_E_UNLOAD: - error = accept_filt_del(accfp); - break; - - case LKM_E_STAT: - error = 0; - break; - - default: - error = EOPNOTSUPP; - break; - } - - return error; -} - -int accept_filt_getopt(struct socket *so, struct sockopt *sopt) { struct accept_filter_arg afa; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index f9820b5bfed..c5e1bc86152 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_syscalls.c,v 1.376 2008/10/22 11:16:29 ad Exp $ */ +/* $NetBSD: vfs_syscalls.c,v 1.377 2008/11/12 12:36:16 ad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.376 2008/10/22 11:16:29 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.377 2008/11/12 12:36:16 ad Exp $"); #include "opt_compat_netbsd.h" #include "opt_compat_43.h" @@ -523,7 +523,6 @@ do_sys_mount(struct lwp *l, struct vfsops *vfsops, const char *type, /* No length supplied, use default for filesystem */ data_len = vfsops->vfs_min_mount_data; if (data_len > VFS_MAX_MOUNT_DATA) { - /* maybe a force loaded old LKM */ error = EINVAL; goto done; } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index d27a0115b6d..1fb0d1365cc 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_vnops.c,v 1.160 2008/08/27 06:28:09 christos Exp $ */ +/* $NetBSD: vfs_vnops.c,v 1.161 2008/11/12 12:36:16 ad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -37,9 +37,8 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.160 2008/08/27 06:28:09 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.161 2008/11/12 12:36:16 ad Exp $"); -#include "fs_union.h" #include "veriexec.h" #include <sys/param.h> @@ -72,9 +71,7 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.160 2008/08/27 06:28:09 christos Exp #include <fs/union/union.h> #endif -#if defined(LKM) || defined(UNION) int (*vn_union_readdir_hook) (struct vnode **, struct file *, struct lwp *); -#endif #include <sys/verified_exec.h> @@ -403,7 +400,6 @@ unionread: if (error) return (error); -#if defined(UNION) || defined(LKM) if (count == auio.uio_resid && vn_union_readdir_hook) { struct vnode *ovp = vp; @@ -413,7 +409,6 @@ unionread: if (vp != ovp) goto unionread; } -#endif /* UNION || LKM */ if (count == auio.uio_resid && (vp->v_vflag & VV_ROOT) && (vp->v_mount->mnt_flag & MNT_UNION)) { |
