kill tsol ("Trusted Solaris") aka TX ("Trusted Extensions")
[unleashed.git] / kernel / os / modconf.c
blob2aac71e0fc1f9f84d1eb758f51bc68f9e06f3c56
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
27 #include <sys/systm.h>
28 #include <sys/param.h>
29 #include <sys/user.h>
30 #include <sys/vm.h>
31 #include <sys/conf.h>
32 #include <sys/class.h>
33 #include <sys/vfs.h>
34 #include <sys/vnode.h>
35 #include <sys/mount.h>
36 #include <sys/systm.h>
37 #include <sys/modctl.h>
38 #include <sys/exec.h>
39 #include <sys/exechdr.h>
40 #include <sys/devops.h>
41 #include <sys/ddi.h>
42 #include <sys/sunddi.h>
43 #include <sys/cmn_err.h>
44 #include <sys/hwconf.h>
45 #include <sys/ddi_impldefs.h>
46 #include <sys/autoconf.h>
47 #include <sys/disp.h>
48 #include <sys/kmem.h>
49 #include <sys/instance.h>
50 #include <sys/modhash.h>
51 #include <sys/dacf.h>
52 #include <sys/debug.h>
53 #include <ipp/ipp.h>
54 #include <sys/strsubr.h>
55 #include <sys/kcpc.h>
56 #include <sys/brand.h>
57 #include <sys/cpc_pcbe.h>
58 #include <sys/kstat.h>
59 #include <sys/socketvar.h>
60 #include <sys/kiconv.h>
62 extern int moddebug;
64 extern struct cb_ops no_cb_ops;
65 extern struct dev_ops nodev_ops;
66 extern struct dev_ops mod_nodev_ops;
68 extern struct modctl *mod_getctl(struct modlinkage *);
69 extern int errsys(), nodev(), nulldev();
71 extern int findmodbyname(char *);
72 extern int mod_getsysnum(char *);
74 extern struct execsw execsw[];
77 * Define dev_ops for unused devopsp entry.
79 struct dev_ops mod_nodev_ops = {
80 DEVO_REV, /* devo_rev */
81 0, /* refcnt */
82 ddi_no_info, /* info */
83 nulldev, /* identify */
84 nulldev, /* probe */
85 ddifail, /* attach */
86 nodev, /* detach */
87 nulldev, /* reset */
88 &no_cb_ops, /* character/block driver operations */
89 (struct bus_ops *)0 /* bus operations for nexus drivers */
93 * Define mod_ops for each supported module type
97 * Null operations; used for uninitialized and "misc" modules.
99 static int mod_null(struct modldrv *, struct modlinkage *);
100 static int mod_infonull(void *, struct modlinkage *, int *);
102 struct mod_ops mod_miscops = {
103 mod_null, mod_null, mod_infonull
106 /* CPU Modules */
107 struct mod_ops mod_cpuops = {
108 mod_null, mod_null, mod_infonull
112 * Cryptographic Modules
114 struct mod_ops mod_cryptoops = {
115 mod_null, mod_null, mod_infonull
119 * IP Policy Modules
121 static int mod_installipp(struct modlipp *, struct modlinkage *);
122 static int mod_removeipp(struct modlipp *, struct modlinkage *);
123 static int mod_infoipp(struct modlipp *, struct modlinkage *, int *);
125 struct mod_ops mod_ippops = {
126 mod_installipp, mod_removeipp, mod_infoipp
130 * Device drivers
132 static int mod_infodrv(struct modldrv *, struct modlinkage *, int *);
133 static int mod_installdrv(struct modldrv *, struct modlinkage *);
134 static int mod_removedrv(struct modldrv *, struct modlinkage *);
136 struct mod_ops mod_driverops = {
137 mod_installdrv, mod_removedrv, mod_infodrv
141 * System calls (new interface)
143 static int mod_infosys(struct modlsys *, struct modlinkage *, int *);
144 static int mod_installsys(struct modlsys *, struct modlinkage *);
145 static int mod_removesys(struct modlsys *, struct modlinkage *);
147 struct mod_ops mod_syscallops = {
148 mod_installsys, mod_removesys, mod_infosys
151 #ifdef _SYSCALL32_IMPL
153 * 32-bit system calls in 64-bit kernel
155 static int mod_infosys32(struct modlsys *, struct modlinkage *, int *);
156 static int mod_installsys32(struct modlsys *, struct modlinkage *);
157 static int mod_removesys32(struct modlsys *, struct modlinkage *);
159 struct mod_ops mod_syscallops32 = {
160 mod_installsys32, mod_removesys32, mod_infosys32
162 #endif /* _SYSCALL32_IMPL */
165 * Filesystems
167 static int mod_infofs(struct modlfs *, struct modlinkage *, int *);
168 static int mod_installfs(struct modlfs *, struct modlinkage *);
169 static int mod_removefs(struct modlfs *, struct modlinkage *);
171 struct mod_ops mod_fsops = {
172 mod_installfs, mod_removefs, mod_infofs
176 * Streams modules.
178 static int mod_infostrmod(struct modlstrmod *, struct modlinkage *, int *);
179 static int mod_installstrmod(struct modlstrmod *, struct modlinkage *);
180 static int mod_removestrmod(struct modlstrmod *, struct modlinkage *);
182 struct mod_ops mod_strmodops = {
183 mod_installstrmod, mod_removestrmod, mod_infostrmod
187 * Socket modules.
189 static int mod_infosockmod(struct modlsockmod *, struct modlinkage *, int *);
190 static int mod_installsockmod(struct modlsockmod *, struct modlinkage *);
191 static int mod_removesockmod(struct modlsockmod *, struct modlinkage *);
193 struct mod_ops mod_sockmodops = {
194 mod_installsockmod, mod_removesockmod, mod_infosockmod
198 * Scheduling classes.
200 static int mod_infosched(struct modlsched *, struct modlinkage *, int *);
201 static int mod_installsched(struct modlsched *, struct modlinkage *);
202 static int mod_removesched(struct modlsched *, struct modlinkage *);
204 struct mod_ops mod_schedops = {
205 mod_installsched, mod_removesched, mod_infosched
209 * Exec file type (like ELF, ...).
211 static int mod_infoexec(struct modlexec *, struct modlinkage *, int *);
212 static int mod_installexec(struct modlexec *, struct modlinkage *);
213 static int mod_removeexec(struct modlexec *, struct modlinkage *);
215 struct mod_ops mod_execops = {
216 mod_installexec, mod_removeexec, mod_infoexec
220 * Dacf (Dynamic Autoconfiguration) modules.
222 static int mod_infodacf(struct modldacf *, struct modlinkage *, int *);
223 static int mod_installdacf(struct modldacf *, struct modlinkage *);
224 static int mod_removedacf(struct modldacf *, struct modlinkage *);
226 struct mod_ops mod_dacfops = {
227 mod_installdacf, mod_removedacf, mod_infodacf
231 * PCBE (Performance Counter BackEnd) modules.
233 static int mod_installpcbe(struct modlpcbe *, struct modlinkage *);
234 static int mod_removepcbe(struct modlpcbe *, struct modlinkage *);
236 struct mod_ops mod_pcbeops = {
237 mod_installpcbe, mod_removepcbe, mod_infonull
241 * Brand modules.
243 static int mod_installbrand(struct modlbrand *, struct modlinkage *);
244 static int mod_removebrand(struct modlbrand *, struct modlinkage *);
246 struct mod_ops mod_brandops = {
247 mod_installbrand, mod_removebrand, mod_infonull
251 * kiconv modules.
253 static int mod_installkiconv(struct modlkiconv *, struct modlinkage *);
254 static int mod_removekiconv(struct modlkiconv *, struct modlinkage *);
256 struct mod_ops mod_kiconvops = {
257 mod_installkiconv, mod_removekiconv, mod_infonull
260 static struct sysent *mod_getsysent(struct modlinkage *, struct sysent *);
262 static char uninstall_err[] = "Cannot uninstall %s; not installed";
265 * Debugging support
267 #define DRV_DBG MODDEBUG_LOADMSG2
269 /*PRINTFLIKE2*/
270 static void mod_dprintf(int flag, const char *format, ...) __KPRINTFLIKE(2);
272 static void
273 mod_dprintf(int flag, const char *format, ...)
275 va_list alist;
277 if ((moddebug & flag) != 0) {
278 va_start(alist, format);
279 (void) vprintf(format, alist);
280 va_end(alist);
285 * Install a module.
286 * (This routine is in the Solaris SPARC DDI/DKI)
289 mod_install(struct modlinkage *modlp)
291 int retval = -1; /* No linkage structures */
292 struct modlmisc **linkpp;
293 struct modlmisc **linkpp1;
295 if (modlp->ml_rev != MODREV_1) {
296 printf("mod_install: modlinkage structure is not MODREV_1\n");
297 return (EINVAL);
299 linkpp = (struct modlmisc **)&modlp->ml_linkage[0];
301 while (*linkpp != NULL) {
302 if ((retval = MODL_INSTALL(*linkpp, modlp)) != 0) {
303 linkpp1 = (struct modlmisc **)&modlp->ml_linkage[0];
305 while (linkpp1 != linkpp) {
306 MODL_REMOVE(*linkpp1, modlp); /* clean up */
307 linkpp1++;
309 break;
311 linkpp++;
313 return (retval);
316 static char *reins_err =
317 "Could not reinstall %s\nReboot to correct the problem";
320 * Remove a module. This is called by the module wrapper routine.
321 * (This routine is in the Solaris SPARC DDI/DKI)
324 mod_remove(struct modlinkage *modlp)
326 int retval = 0;
327 struct modlmisc **linkpp, *last_linkp;
329 linkpp = (struct modlmisc **)&modlp->ml_linkage[0];
331 while (*linkpp != NULL) {
332 if ((retval = MODL_REMOVE(*linkpp, modlp)) != 0) {
333 last_linkp = *linkpp;
334 linkpp = (struct modlmisc **)&modlp->ml_linkage[0];
335 while (*linkpp != last_linkp) {
336 if (MODL_INSTALL(*linkpp, modlp) != 0) {
337 cmn_err(CE_WARN, reins_err,
338 (*linkpp)->misc_linkinfo);
339 break;
341 linkpp++;
343 break;
345 linkpp++;
347 return (retval);
351 * Get module status.
352 * (This routine is in the Solaris SPARC DDI/DKI)
355 mod_info(struct modlinkage *modlp, struct modinfo *modinfop)
357 int i;
358 int retval = 0;
359 struct modspecific_info *msip;
360 struct modlmisc **linkpp;
362 modinfop->mi_rev = modlp->ml_rev;
364 linkpp = (struct modlmisc **)modlp->ml_linkage;
365 msip = &modinfop->mi_msinfo[0];
367 for (i = 0; i < MODMAXLINK; i++) {
368 if (*linkpp == NULL) {
369 msip->msi_linkinfo[0] = '\0';
370 } else {
371 (void) strncpy(msip->msi_linkinfo,
372 (*linkpp)->misc_linkinfo, MODMAXLINKINFOLEN);
373 retval = MODL_INFO(*linkpp, modlp, &msip->msi_p0);
374 if (retval != 0)
375 break;
376 linkpp++;
378 msip++;
381 if (modinfop->mi_info == MI_INFO_LINKAGE) {
383 * Slight kludge used to extract the address of the
384 * modlinkage structure from the module (just after
385 * loading a module for the very first time)
387 modinfop->mi_base = (void *)modlp;
390 if (retval == 0)
391 return (1);
392 return (0);
396 * Get module name.
398 const char *
399 mod_modname(struct modlinkage *modlp)
401 struct modctl *mcp;
403 if ((mcp = mod_getctl(modlp)) == NULL)
404 return (NULL);
406 return (mcp->mod_modname);
410 * Null operation; return 0.
412 /*ARGSUSED*/
413 static int
414 mod_null(struct modldrv *modl, struct modlinkage *modlp)
416 return (0);
420 * Status for User modules.
422 /*ARGSUSED*/
423 static int
424 mod_infonull(void *modl, struct modlinkage *modlp, int *p0)
426 *p0 = -1; /* for modinfo display */
427 return (0);
431 * Driver status info
433 /*ARGSUSED*/
434 static int
435 mod_infodrv(struct modldrv *modl, struct modlinkage *modlp, int *p0)
437 struct modctl *mcp;
438 char *mod_name;
440 if ((mcp = mod_getctl(modlp)) == NULL) {
441 *p0 = -1;
442 return (0); /* driver is not yet installed */
445 mod_name = mcp->mod_modname;
447 *p0 = ddi_name_to_major(mod_name);
448 return (0);
452 * Manage dacf (device autoconfiguration) modules
455 /*ARGSUSED*/
456 static int
457 mod_infodacf(struct modldacf *modl, struct modlinkage *modlp, int *p0)
459 if (mod_getctl(modlp) == NULL) {
460 *p0 = -1;
461 return (0); /* module is not yet installed */
464 *p0 = 0;
465 return (0);
468 static int
469 mod_installdacf(struct modldacf *modl, struct modlinkage *modlp)
471 struct modctl *mcp;
473 if ((mcp = mod_getctl(modlp)) == NULL)
474 return (EINVAL);
475 return (dacf_module_register(mcp->mod_modname, modl->dacf_dacfsw));
478 /*ARGSUSED*/
479 static int
480 mod_removedacf(struct modldacf *modl, struct modlinkage *modlp)
482 struct modctl *mcp;
484 if ((mcp = mod_getctl(modlp)) == NULL)
485 return (EINVAL);
486 return (dacf_module_unregister(mcp->mod_modname));
490 * Manage PCBE (Performance Counter BackEnd) modules.
492 /*ARGSUSED*/
493 static int
494 mod_installpcbe(struct modlpcbe *modl, struct modlinkage *modlp)
496 if (modl->pcbe_ops->pcbe_ver != PCBE_VER_1) {
497 cmn_err(CE_WARN, "pcbe '%s' version mismatch",
498 modl->pcbe_linkinfo);
499 return (EINVAL);
502 kcpc_register_pcbe(modl->pcbe_ops);
503 return (0);
507 * PCBEs may not be unloaded. It would make CPC locking too complex, and since
508 * PCBEs are loaded once and used for life, there is no harm done in leaving
509 * them in the system.
511 /*ARGSUSED*/
512 static int
513 mod_removepcbe(struct modlpcbe *modl, struct modlinkage *modlp)
515 return (EBUSY);
519 * Manage BrandZ modules.
521 /*ARGSUSED*/
522 static int
523 mod_installbrand(struct modlbrand *modl, struct modlinkage *modlp)
525 return (brand_register(modl->brand_branddef));
528 /*ARGSUSED*/
529 static int
530 mod_removebrand(struct modlbrand *modl, struct modlinkage *modlp)
532 return (brand_unregister(modl->brand_branddef));
536 * Install a new driver
538 static int
539 mod_installdrv(struct modldrv *modl, struct modlinkage *modlp)
541 struct modctl *mcp;
542 struct dev_ops *ops;
543 char *modname;
544 major_t major;
545 struct dev_ops *dp;
546 struct devnames *dnp;
547 struct streamtab *str;
548 cdevsw_impl_t *cdp;
549 uint_t sqtype;
550 uint_t qflag;
551 uint_t flag;
552 int err = 0;
554 /* sanity check module */
555 if ((mcp = mod_getctl(modlp)) == NULL) {
556 cmn_err(CE_WARN, "mod_install: bad module linkage data");
557 err = ENXIO;
558 goto done;
560 modname = mcp->mod_modname;
562 /* Sanity check modname */
563 if ((major = ddi_name_to_major(modname)) == DDI_MAJOR_T_NONE) {
564 #ifdef DEBUG
565 cmn_err(CE_WARN,
566 "mod_installdrv: no major number for %s", modname);
567 #endif
568 err = ENXIO;
569 goto done;
572 /* Verify MP safety flag */
573 ops = modl->drv_dev_ops;
574 if (ops->devo_bus_ops == NULL && ops->devo_cb_ops != NULL &&
575 !(ops->devo_cb_ops->cb_flag & D_MP)) {
576 cmn_err(CE_WARN,
577 "mod_installdrv: MT-unsafe driver '%s' rejected", modname);
578 err = ENXIO;
579 goto done;
583 /* Is bus_map_fault signature correct (version 8 and higher)? */
584 if (ops->devo_bus_ops != NULL &&
585 ops->devo_bus_ops->bus_map_fault != NULL &&
586 ops->devo_bus_ops->bus_map_fault != i_ddi_map_fault &&
587 ops->devo_bus_ops->busops_rev < BUSO_REV_8) {
589 cmn_err(CE_WARN,
590 "mod_installdrv: busops' revision of '%s' is too low"
591 " (must be at least 8)", modname);
592 err = ENXIO;
593 goto done;
597 /* Make sure the driver is uninstalled */
598 dnp = &devnamesp[major];
599 LOCK_DEV_OPS(&dnp->dn_lock);
600 dp = devopsp[major];
602 if (dnp->dn_flags & (DN_DRIVER_REMOVED|DN_DRIVER_INACTIVE)) {
603 #ifdef DEBUG
604 cmn_err(CE_CONT,
605 "mod_installdrv: driver %s not installed", modname);
606 #endif
607 err = ENXIO;
608 goto unlock;
611 if (dp != &nodev_ops && dp != &mod_nodev_ops) {
612 cmn_err(CE_WARN,
613 "mod_installdrv: driver already installed %s", modname);
614 err = EALREADY;
615 goto unlock;
618 devopsp[major] = ops; /* setup devopsp */
620 if ((str = STREAMSTAB(major)) != NULL) { /* streams driver */
621 flag = CBFLAG(major);
622 if ((err = devflg_to_qflag(str, flag, &qflag, &sqtype)) != 0)
623 goto unlock;
624 cdp = &devimpl[major];
625 ASSERT(cdp->d_str == NULL);
626 cdp->d_str = str;
627 cdp->d_qflag = qflag | QISDRV;
628 cdp->d_sqtype = sqtype;
631 if (ops->devo_bus_ops == NULL)
632 dnp->dn_flags |= DN_LEAF_DRIVER;
634 unlock:
635 UNLOCK_DEV_OPS(&dnp->dn_lock);
636 done:
637 return (err);
640 static int
641 mod_removedrv(struct modldrv *modl, struct modlinkage *modlp)
643 struct modctl *mcp;
644 struct dev_ops *ops;
645 struct devnames *dnp;
646 struct dev_ops *dp;
647 major_t major;
648 char *modname;
649 extern kthread_id_t mod_aul_thread;
650 struct streamtab *str;
651 cdevsw_impl_t *cdp;
652 int err = 0;
654 /* Don't auto unload modules on if moddebug flag is set */
655 if ((moddebug & MODDEBUG_NOAUL_DRV) && (mod_aul_thread == curthread)) {
656 err = EBUSY;
657 goto done;
660 /* Verify modname has a driver major */
661 mcp = mod_getctl(modlp);
662 ASSERT(mcp != NULL);
663 modname = mcp->mod_modname;
665 if ((major = ddi_name_to_major(modname)) == -1) {
666 cmn_err(CE_WARN, uninstall_err, modname);
667 err = EINVAL;
668 goto done;
671 ops = modl->drv_dev_ops;
672 dnp = &(devnamesp[major]);
673 LOCK_DEV_OPS(&(dnp->dn_lock));
675 dp = devopsp[major];
677 if (dp != ops) {
678 cmn_err(CE_NOTE, "mod_removedrv: mismatched driver for %s",
679 modname);
680 err = EBUSY;
681 goto unlock;
685 * A driver is not unloadable if its dev_ops are held
687 if (!DRV_UNLOADABLE(dp)) {
688 mod_dprintf(DRV_DBG, "Cannot unload device driver <%s>,"
689 " refcnt %d\n", modname, dp->devo_refcnt);
690 err = EBUSY;
691 goto unlock;
695 * OK to unload.
697 if ((str = STREAMSTAB(major)) != NULL) { /* streams driver */
698 cdp = &devimpl[major];
699 ASSERT(cdp->d_str == str);
700 cdp->d_str = NULL;
702 /* check for reference to per-dev syncq */
703 if (cdp->d_dmp != NULL) {
704 rele_dm(cdp->d_dmp);
705 cdp->d_dmp = NULL;
709 devopsp[major] = &mod_nodev_ops;
710 dnp->dn_flags &= ~(DN_DRIVER_HELD|DN_NO_AUTODETACH);
712 unlock:
713 UNLOCK_DEV_OPS(&(dnp->dn_lock));
714 done:
715 return (err);
719 * System call subroutines
723 * Compute system call number for given sysent and sysent table
725 static int
726 mod_infosysnum(struct modlinkage *modlp, struct sysent table[])
728 struct sysent *sysp;
730 if ((sysp = mod_getsysent(modlp, table)) == NULL)
731 return (-1);
732 return ((int)(sysp - table));
736 * Put a loadable system call entry into a sysent table.
738 static int
739 mod_installsys_sysent(
740 struct modlsys *modl,
741 struct modlinkage *modlp,
742 struct sysent table[])
744 struct sysent *sysp;
745 struct sysent *mp;
747 #ifdef DEBUG
749 * Before we even play with the sysent table, sanity check the
750 * incoming flags to make sure the entry is valid
752 switch (modl->sys_sysent->sy_flags & SE_RVAL_MASK) {
753 case SE_32RVAL1:
754 /* only r_val1 returned */
755 case SE_32RVAL1 | SE_32RVAL2:
756 /* r_val1 and r_val2 returned */
757 case SE_64RVAL:
758 /* 64-bit rval returned */
759 break;
760 default:
761 cmn_err(CE_WARN, "loadable syscall: %p: bad rval flags %x",
762 (void *)modl, modl->sys_sysent->sy_flags);
763 return (ENOSYS);
765 #endif
766 if ((sysp = mod_getsysent(modlp, table)) == NULL)
767 return (ENOSPC);
770 * We should only block here until the reader in syscall gives
771 * up the lock. Multiple writers are prevented in the mod layer.
773 rw_enter(sysp->sy_lock, RW_WRITER);
774 mp = modl->sys_sysent;
775 sysp->sy_narg = mp->sy_narg;
776 sysp->sy_call = mp->sy_call;
779 * clear the old call method flag, and get the new one from the module.
781 sysp->sy_flags &= ~SE_ARGC;
782 sysp->sy_flags |= SE_LOADED |
783 (mp->sy_flags & (SE_ARGC | SE_NOUNLOAD | SE_RVAL_MASK));
786 * If the syscall doesn't need or want unloading, it can avoid
787 * the locking overhead on each entry. Convert the sysent to a
788 * normal non-loadable entry in that case.
790 if (mp->sy_flags & SE_NOUNLOAD) {
791 if (mp->sy_flags & SE_ARGC) {
792 sysp->sy_callc = (int64_t (*)())mp->sy_call;
793 } else {
794 sysp->sy_callc = syscall_ap;
796 sysp->sy_flags &= ~SE_LOADABLE;
798 rw_exit(sysp->sy_lock);
799 return (0);
803 * Remove a loadable system call entry from a sysent table.
805 static int
806 mod_removesys_sysent(
807 struct modlsys *modl,
808 struct modlinkage *modlp,
809 struct sysent table[])
811 struct sysent *sysp;
813 if ((sysp = mod_getsysent(modlp, table)) == NULL ||
814 (sysp->sy_flags & (SE_LOADABLE | SE_NOUNLOAD)) == 0 ||
815 sysp->sy_call != modl->sys_sysent->sy_call) {
817 struct modctl *mcp = mod_getctl(modlp);
818 char *modname = mcp->mod_modname;
820 cmn_err(CE_WARN, uninstall_err, modname);
821 return (EINVAL);
824 /* If we can't get the write lock, we can't unlink from the system */
826 if (!(moddebug & MODDEBUG_NOAUL_SYS) &&
827 rw_tryenter(sysp->sy_lock, RW_WRITER)) {
829 * Check the flags to be sure the syscall is still
830 * (un)loadable.
831 * If SE_NOUNLOAD is set, SE_LOADABLE will not be.
833 if ((sysp->sy_flags & (SE_LOADED | SE_LOADABLE)) ==
834 (SE_LOADED | SE_LOADABLE)) {
835 sysp->sy_flags &= ~SE_LOADED;
836 sysp->sy_callc = loadable_syscall;
837 sysp->sy_call = (int (*)())nosys;
838 rw_exit(sysp->sy_lock);
839 return (0);
841 rw_exit(sysp->sy_lock);
843 return (EBUSY);
847 * System call status info
849 /*ARGSUSED*/
850 static int
851 mod_infosys(struct modlsys *modl, struct modlinkage *modlp, int *p0)
853 *p0 = mod_infosysnum(modlp, sysent);
854 return (0);
858 * Link a system call into the system by setting the proper sysent entry.
859 * Called from the module's _init routine.
861 static int
862 mod_installsys(struct modlsys *modl, struct modlinkage *modlp)
864 return (mod_installsys_sysent(modl, modlp, sysent));
868 * Unlink a system call from the system.
869 * Called from a modules _fini routine.
871 static int
872 mod_removesys(struct modlsys *modl, struct modlinkage *modlp)
874 return (mod_removesys_sysent(modl, modlp, sysent));
877 #ifdef _SYSCALL32_IMPL
880 * 32-bit system call status info
882 /*ARGSUSED*/
883 static int
884 mod_infosys32(struct modlsys *modl, struct modlinkage *modlp, int *p0)
886 *p0 = mod_infosysnum(modlp, sysent32);
887 return (0);
891 * Link the 32-bit syscall into the system by setting the proper sysent entry.
892 * Also called from the module's _init routine.
894 static int
895 mod_installsys32(struct modlsys *modl, struct modlinkage *modlp)
897 return (mod_installsys_sysent(modl, modlp, sysent32));
901 * Unlink the 32-bit flavor of a system call from the system.
902 * Also called from a module's _fini routine.
904 static int
905 mod_removesys32(struct modlsys *modl, struct modlinkage *modlp)
907 return (mod_removesys_sysent(modl, modlp, sysent32));
910 #endif /* _SYSCALL32_IMPL */
913 * Filesystem status info
915 /*ARGSUSED*/
916 static int
917 mod_infofs(struct modlfs *modl, struct modlinkage *modlp, int *p0)
919 struct vfssw *vswp;
921 RLOCK_VFSSW();
922 if ((vswp = vfs_getvfsswbyname(modl->fs_vfsdef->name)) == NULL)
923 *p0 = -1;
924 else {
925 *p0 = vswp - vfssw;
926 vfs_unrefvfssw(vswp);
928 RUNLOCK_VFSSW();
929 return (0);
933 * Install a filesystem.
935 /*ARGSUSED1*/
936 static int
937 mod_installfs(struct modlfs *modl, struct modlinkage *modlp)
939 struct vfssw *vswp;
940 struct modctl *mcp;
941 char *fsname;
942 char ksname[KSTAT_STRLEN + 1];
943 int fstype; /* index into vfssw[] and vsanchor_fstype[] */
944 int allocated;
945 int err;
946 int vsw_stats_enabled;
947 /* Not for public consumption so these aren't in a header file */
948 extern int vopstats_enabled;
949 extern vopstats_t **vopstats_fstype;
950 extern kstat_t *new_vskstat(char *, vopstats_t *);
951 extern void initialize_vopstats(vopstats_t *);
953 if (modl->fs_vfsdef->def_version == VFSDEF_VERSION) {
954 /* Version matched */
955 fsname = modl->fs_vfsdef->name;
956 } else {
957 if ((modl->fs_vfsdef->def_version > 0) &&
958 (modl->fs_vfsdef->def_version < VFSDEF_VERSION)) {
959 /* Older VFSDEF_VERSION */
960 fsname = modl->fs_vfsdef->name;
961 } else if ((mcp = mod_getctl(modlp)) != NULL) {
962 /* Pre-VFSDEF_VERSION */
963 fsname = mcp->mod_modname;
964 } else {
965 /* If all else fails... */
966 fsname = "<unknown file system type>";
969 cmn_err(CE_WARN, "file system '%s' version mismatch", fsname);
970 return (ENXIO);
973 allocated = 0;
975 WLOCK_VFSSW();
976 if ((vswp = vfs_getvfsswbyname(fsname)) == NULL) {
977 if ((vswp = allocate_vfssw(fsname)) == NULL) {
978 WUNLOCK_VFSSW();
980 * See 1095689. If this message appears, then
981 * we either need to make the vfssw table bigger
982 * statically, or make it grow dynamically.
984 cmn_err(CE_WARN, "no room for '%s' in vfssw!", fsname);
985 return (ENXIO);
987 allocated = 1;
989 ASSERT(vswp != NULL);
991 fstype = vswp - vfssw; /* Pointer arithmetic to get the fstype */
993 /* Turn on everything by default *except* VSW_STATS */
994 vswp->vsw_flag = modl->fs_vfsdef->flags & ~(VSW_STATS);
996 if (modl->fs_vfsdef->flags & VSW_HASPROTO) {
997 vfs_mergeopttbl(&vfs_mntopts, modl->fs_vfsdef->optproto,
998 &vswp->vsw_optproto);
999 } else {
1000 vfs_copyopttbl(&vfs_mntopts, &vswp->vsw_optproto);
1003 if (modl->fs_vfsdef->flags & VSW_CANRWRO) {
1005 * This obviously implies VSW_CANREMOUNT.
1007 vswp->vsw_flag |= VSW_CANREMOUNT;
1011 * If stats are enabled system wide and for this fstype, then
1012 * set the VSW_STATS flag in the proper vfssw[] table entry.
1014 if (vopstats_enabled && modl->fs_vfsdef->flags & VSW_STATS) {
1015 vswp->vsw_flag |= VSW_STATS;
1018 if (modl->fs_vfsdef->init == NULL)
1019 err = EFAULT;
1020 else
1021 err = (*(modl->fs_vfsdef->init))(fstype, fsname);
1023 if (err != 0) {
1024 if (allocated) {
1025 kmem_free(vswp->vsw_name, strlen(vswp->vsw_name)+1);
1026 vswp->vsw_name = "";
1028 vswp->vsw_flag = 0;
1029 vswp->vsw_init = NULL;
1032 /* We don't want to hold the vfssw[] write lock over a kmem_alloc() */
1033 vsw_stats_enabled = vswp->vsw_flag & VSW_STATS;
1035 vfs_unrefvfssw(vswp);
1036 WUNLOCK_VFSSW();
1038 /* If everything is on, set up the per-fstype vopstats */
1039 if (vsw_stats_enabled && vopstats_enabled &&
1040 vopstats_fstype && vopstats_fstype[fstype] == NULL) {
1041 (void) strlcpy(ksname, VOPSTATS_STR, sizeof (ksname));
1042 (void) strlcat(ksname, vfssw[fstype].vsw_name, sizeof (ksname));
1043 vopstats_fstype[fstype] =
1044 kmem_alloc(sizeof (vopstats_t), KM_SLEEP);
1045 initialize_vopstats(vopstats_fstype[fstype]);
1046 (void) new_vskstat(ksname, vopstats_fstype[fstype]);
1048 return (err);
1052 * Remove a filesystem
1054 static int
1055 mod_removefs(struct modlfs *modl, struct modlinkage *modlp)
1057 struct vfssw *vswp;
1058 struct modctl *mcp;
1059 char *modname;
1061 if (moddebug & MODDEBUG_NOAUL_FS)
1062 return (EBUSY);
1064 WLOCK_VFSSW();
1065 if ((vswp = vfs_getvfsswbyname(modl->fs_vfsdef->name)) == NULL) {
1066 mcp = mod_getctl(modlp);
1067 ASSERT(mcp != NULL);
1068 modname = mcp->mod_modname;
1069 WUNLOCK_VFSSW();
1070 cmn_err(CE_WARN, uninstall_err, modname);
1071 return (EINVAL);
1073 if (vswp->vsw_count != 1) {
1074 vfs_unrefvfssw(vswp);
1075 WUNLOCK_VFSSW();
1076 return (EBUSY);
1080 * A mounted filesystem could still have vsw_count = 0
1081 * so we must check whether anyone is actually using our ops
1083 if (vfs_opsinuse(&vswp->vsw_vfsops)) {
1084 vfs_unrefvfssw(vswp);
1085 WUNLOCK_VFSSW();
1086 return (EBUSY);
1089 vfs_freeopttbl(&vswp->vsw_optproto);
1090 vswp->vsw_optproto.mo_count = 0;
1092 vswp->vsw_flag = 0;
1093 vswp->vsw_init = NULL;
1094 vfs_unrefvfssw(vswp);
1095 WUNLOCK_VFSSW();
1096 return (0);
1100 * Get status of a streams module.
1102 /*ARGSUSED*/
1103 static int
1104 mod_infostrmod(struct modlstrmod *modl, struct modlinkage *modlp, int *p0)
1106 *p0 = -1; /* no useful info */
1107 return (0);
1112 * Install a streams module.
1114 /*ARGSUSED*/
1115 static int
1116 mod_installstrmod(struct modlstrmod *modl, struct modlinkage *modlp)
1118 struct fmodsw *fp = modl->strmod_fmodsw;
1120 if (!(fp->f_flag & D_MP)) {
1121 cmn_err(CE_WARN, "mod_install: MT-unsafe strmod '%s' rejected",
1122 fp->f_name);
1123 return (ENXIO);
1126 return (fmodsw_register(fp->f_name, fp->f_str, fp->f_flag));
1130 * Remove a streams module.
1132 /*ARGSUSED*/
1133 static int
1134 mod_removestrmod(struct modlstrmod *modl, struct modlinkage *modlp)
1136 if (moddebug & MODDEBUG_NOAUL_STR)
1137 return (EBUSY);
1139 return (fmodsw_unregister(modl->strmod_fmodsw->f_name));
1143 * Get status of a socket module.
1145 /*ARGSUSED*/
1146 static int
1147 mod_infosockmod(struct modlsockmod *modl, struct modlinkage *modlp, int *p0)
1149 *p0 = -1; /* no useful info */
1150 return (0);
1154 * Install a socket module.
1156 /*ARGSUSED*/
1157 static int
1158 mod_installsockmod(struct modlsockmod *modl, struct modlinkage *modlp)
1160 struct modctl *mcp;
1161 char *mod_name;
1163 mcp = mod_getctl(modlp);
1164 ASSERT(mcp != NULL);
1165 mod_name = mcp->mod_modname;
1166 if (strcmp(mod_name, modl->sockmod_reg_info->smod_name) != 0) {
1167 #ifdef DEBUG
1168 cmn_err(CE_CONT, "mod_installsockmod: different names"
1169 " %s != %s \n", mod_name,
1170 modl->sockmod_reg_info->smod_name);
1171 #endif
1172 return (EINVAL);
1176 * Register module.
1178 return (smod_register(modl->sockmod_reg_info));
1182 * Remove a socket module.
1184 /*ARGSUSED*/
1185 static int
1186 mod_removesockmod(struct modlsockmod *modl, struct modlinkage *modlp)
1189 * unregister from the global socket creation table
1190 * check the refcnt in the lookup table
1192 return (smod_unregister(modl->sockmod_reg_info->smod_name));
1196 * Get status of a scheduling class module.
1198 /*ARGSUSED1*/
1199 static int
1200 mod_infosched(struct modlsched *modl, struct modlinkage *modlp, int *p0)
1202 int status;
1203 auto id_t cid;
1205 status = getcidbyname(modl->sched_class->cl_name, &cid);
1207 if (status != 0)
1208 *p0 = -1;
1209 else
1210 *p0 = cid;
1212 return (0);
1216 * Install a scheduling class module.
1218 /*ARGSUSED1*/
1219 static int
1220 mod_installsched(struct modlsched *modl, struct modlinkage *modlp)
1222 sclass_t *clp;
1223 int status;
1224 id_t cid;
1227 * See if module is already installed.
1229 mutex_enter(&class_lock);
1230 status = alloc_cid(modl->sched_class->cl_name, &cid);
1231 mutex_exit(&class_lock);
1232 ASSERT(status == 0);
1233 clp = &sclass[cid];
1234 rw_enter(clp->cl_lock, RW_WRITER);
1235 if (SCHED_INSTALLED(clp)) {
1236 printf("scheduling class %s is already installed\n",
1237 modl->sched_class->cl_name);
1238 rw_exit(clp->cl_lock);
1239 return (EBUSY); /* it's already there */
1242 clp->cl_init = modl->sched_class->cl_init;
1243 clp->cl_funcs = modl->sched_class->cl_funcs;
1244 modl->sched_class = clp;
1245 disp_add(clp);
1246 loaded_classes++; /* for priocntl system call */
1247 rw_exit(clp->cl_lock);
1248 return (0);
1252 * Remove a scheduling class module.
1254 * we only null out the init func and the class functions because
1255 * once a class has been loaded it has that slot in the class
1256 * array until the next reboot. We don't decrement loaded_classes
1257 * because this keeps count of the number of classes that have
1258 * been loaded for this session. It will have to be this way until
1259 * we implement the class array as a linked list and do true
1260 * dynamic allocation.
1262 static int
1263 mod_removesched(struct modlsched *modl, struct modlinkage *modlp)
1265 int status;
1266 sclass_t *clp;
1267 struct modctl *mcp;
1268 char *modname;
1269 id_t cid;
1271 status = getcidbyname(modl->sched_class->cl_name, &cid);
1272 if (status != 0) {
1273 mcp = mod_getctl(modlp);
1274 ASSERT(mcp != NULL);
1275 modname = mcp->mod_modname;
1276 cmn_err(CE_WARN, uninstall_err, modname);
1277 return (EINVAL);
1279 clp = &sclass[cid];
1280 if (moddebug & MODDEBUG_NOAUL_SCHED ||
1281 !rw_tryenter(clp->cl_lock, RW_WRITER))
1282 return (EBUSY);
1284 clp->cl_init = NULL;
1285 clp->cl_funcs = NULL;
1286 rw_exit(clp->cl_lock);
1287 return (0);
1291 * Get status of an exec module.
1293 /*ARGSUSED1*/
1294 static int
1295 mod_infoexec(struct modlexec *modl, struct modlinkage *modlp, int *p0)
1297 struct execsw *eswp;
1299 if ((eswp = findexecsw(modl->exec_execsw->exec_magic)) == NULL)
1300 *p0 = -1;
1301 else
1302 *p0 = eswp - execsw;
1304 return (0);
1308 * Install an exec module.
1310 static int
1311 mod_installexec(struct modlexec *modl, struct modlinkage *modlp)
1313 struct execsw *eswp;
1314 struct modctl *mcp;
1315 char *modname;
1316 char *magic;
1317 size_t magic_size;
1320 * See if execsw entry is already allocated. Can't use findexectype()
1321 * because we may get a recursive call to here.
1324 if ((eswp = findexecsw(modl->exec_execsw->exec_magic)) == NULL) {
1325 mcp = mod_getctl(modlp);
1326 ASSERT(mcp != NULL);
1327 modname = mcp->mod_modname;
1328 magic = modl->exec_execsw->exec_magic;
1329 magic_size = modl->exec_execsw->exec_maglen;
1330 if ((eswp = allocate_execsw(modname, magic, magic_size)) ==
1331 NULL) {
1332 printf("no unused entries in 'execsw'\n");
1333 return (ENOSPC);
1336 if (eswp->exec_func != NULL) {
1337 printf("exec type %x is already installed\n",
1338 *eswp->exec_magic);
1339 return (EBUSY); /* it's already there! */
1342 rw_enter(eswp->exec_lock, RW_WRITER);
1343 eswp->exec_func = modl->exec_execsw->exec_func;
1344 eswp->exec_core = modl->exec_execsw->exec_core;
1345 rw_exit(eswp->exec_lock);
1347 return (0);
1351 * Remove an exec module.
1353 static int
1354 mod_removeexec(struct modlexec *modl, struct modlinkage *modlp)
1356 struct execsw *eswp;
1357 struct modctl *mcp;
1358 char *modname;
1360 eswp = findexecsw(modl->exec_execsw->exec_magic);
1361 if (eswp == NULL) {
1362 mcp = mod_getctl(modlp);
1363 ASSERT(mcp != NULL);
1364 modname = mcp->mod_modname;
1365 cmn_err(CE_WARN, uninstall_err, modname);
1366 return (EINVAL);
1368 if (moddebug & MODDEBUG_NOAUL_EXEC ||
1369 !rw_tryenter(eswp->exec_lock, RW_WRITER))
1370 return (EBUSY);
1371 eswp->exec_func = NULL;
1372 eswp->exec_core = NULL;
1373 rw_exit(eswp->exec_lock);
1374 return (0);
1378 * Find a free sysent entry or check if the specified one is free.
1380 static struct sysent *
1381 mod_getsysent(struct modlinkage *modlp, struct sysent *se)
1383 int sysnum;
1384 struct modctl *mcp;
1385 char *mod_name;
1387 if ((mcp = mod_getctl(modlp)) == NULL) {
1389 * This happens when we're looking up the module
1390 * pointer as part of a stub installation. So
1391 * there's no need to whine at this point.
1393 return (NULL);
1396 mod_name = mcp->mod_modname;
1398 if ((sysnum = mod_getsysnum(mod_name)) == -1) {
1399 cmn_err(CE_WARN, "system call missing from bind file");
1400 return (NULL);
1403 if (sysnum > 0 && sysnum < NSYSCALL &&
1404 (se[sysnum].sy_flags & (SE_LOADABLE | SE_NOUNLOAD)))
1405 return (se + sysnum);
1407 cmn_err(CE_WARN, "system call entry %d is already in use", sysnum);
1408 return (NULL);
1412 * IP Policy Modules.
1414 /*ARGSUSED*/
1415 static int
1416 mod_infoipp(struct modlipp *modl, struct modlinkage *modlp, int *p0)
1418 struct modctl *mcp = mod_getctl(modlp);
1419 ipp_mod_id_t mid;
1421 if (mcp == NULL) {
1422 *p0 = -1;
1423 return (0); /* module is not yet installed */
1426 mid = ipp_mod_lookup(mcp->mod_modname);
1428 *p0 = mid;
1429 return (0);
1432 static int
1433 mod_installipp(struct modlipp *modl, struct modlinkage *modlp)
1435 struct modctl *mcp = mod_getctl(modlp);
1437 ASSERT(mcp != NULL);
1438 return (ipp_mod_register(mcp->mod_modname, modl->ipp_ops));
1441 /*ARGSUSED*/
1442 static int
1443 mod_removeipp(struct modlipp *modl, struct modlinkage *modlp)
1445 struct modctl *mcp = mod_getctl(modlp);
1446 extern kthread_id_t mod_aul_thread;
1447 ipp_mod_id_t mid;
1449 ASSERT(mcp != NULL);
1451 if ((moddebug & MODDEBUG_NOAUL_IPP) && (mod_aul_thread == curthread))
1452 return (EBUSY);
1454 mid = ipp_mod_lookup(mcp->mod_modname);
1455 ASSERT(mid != IPP_MOD_INVAL);
1457 return (ipp_mod_unregister(mid));
1461 * Manage kiconv modules.
1463 /*ARGSUSED*/
1464 static int
1465 mod_installkiconv(struct modlkiconv *modl, struct modlinkage *modlp)
1467 return (kiconv_register_module(modl->kiconv_moddef));
1470 /*ARGSUSED*/
1471 static int
1472 mod_removekiconv(struct modlkiconv *modl, struct modlinkage *modlp)
1474 return (kiconv_unregister_module(modl->kiconv_moddef));