xref: /titanic_41/usr/src/uts/common/os/modconf.c (revision 7010c12ad3ac2cada55cf126121a8c46957d3632)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <sys/types.h>
29 #include <sys/systm.h>
30 #include <sys/param.h>
31 #include <sys/user.h>
32 #include <sys/vm.h>
33 #include <sys/conf.h>
34 #include <sys/class.h>
35 #include <sys/vfs.h>
36 #include <sys/vnode.h>
37 #include <sys/mount.h>
38 #include <sys/systm.h>
39 #include <sys/modctl.h>
40 #include <sys/exec.h>
41 #include <sys/exechdr.h>
42 #include <sys/devops.h>
43 #include <sys/ddi.h>
44 #include <sys/sunddi.h>
45 #include <sys/cmn_err.h>
46 #include <sys/hwconf.h>
47 #include <sys/ddi_impldefs.h>
48 #include <sys/autoconf.h>
49 #include <sys/disp.h>
50 #include <sys/kmem.h>
51 #include <sys/instance.h>
52 #include <sys/modhash.h>
53 #include <sys/dacf.h>
54 #include <sys/debug.h>
55 #include <ipp/ipp.h>
56 #include <sys/strsubr.h>
57 #include <sys/kcpc.h>
58 #include <sys/cpc_pcbe.h>
59 #include <sys/kstat.h>
60 #include <sys/fs/sdev_node.h>
61 
62 extern int moddebug;
63 
64 extern struct cb_ops no_cb_ops;
65 extern struct dev_ops nodev_ops;
66 extern struct dev_ops mod_nodev_ops;
67 
68 extern struct modctl *mod_getctl(struct modlinkage *);
69 extern int errsys(), nodev(), nulldev();
70 
71 extern int findmodbyname(char *);
72 extern int mod_getsysnum(char *);
73 
74 extern struct execsw execsw[];
75 
76 /*
77  * Define dev_ops for unused devopsp entry.
78  */
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 */
90 };
91 
92 /*
93  * Define mod_ops for each supported module type
94  */
95 
96 /*
97  * Null operations; used for uninitialized and "misc" modules.
98  */
99 static int mod_null(struct modldrv *, struct modlinkage *);
100 static int mod_infonull(void *, struct modlinkage *, int *);
101 
102 struct mod_ops mod_miscops = {
103 	mod_null, mod_null, mod_infonull
104 };
105 
106 /* CPU Modules */
107 struct mod_ops mod_cpuops = {
108 	mod_null, mod_null, mod_infonull
109 };
110 
111 /*
112  * Cryptographic Modules
113  */
114 struct mod_ops mod_cryptoops = {
115 	mod_null, mod_null, mod_infonull
116 };
117 
118 /*
119  * IP Policy Modules
120  */
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 *);
124 
125 struct mod_ops mod_ippops = {
126 	mod_installipp, mod_removeipp, mod_infoipp
127 };
128 
129 /*
130  * Device drivers
131  */
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 *);
135 
136 struct mod_ops mod_driverops = {
137 	mod_installdrv, mod_removedrv, mod_infodrv
138 };
139 
140 /*
141  * System calls (new interface)
142  */
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 *);
146 
147 struct mod_ops mod_syscallops = {
148 	mod_installsys, mod_removesys, mod_infosys
149 };
150 
151 #ifdef _SYSCALL32_IMPL
152 /*
153  * 32-bit system calls in 64-bit kernel
154  */
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 *);
158 
159 struct mod_ops mod_syscallops32 = {
160 	mod_installsys32, mod_removesys32, mod_infosys32
161 };
162 #endif	/* _SYSCALL32_IMPL */
163 
164 /*
165  * Filesystems
166  */
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 *);
170 
171 struct mod_ops mod_fsops = {
172 	mod_installfs, mod_removefs, mod_infofs
173 };
174 
175 /*
176  * Streams modules.
177  */
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 *);
181 
182 struct mod_ops mod_strmodops = {
183 	mod_installstrmod, mod_removestrmod, mod_infostrmod
184 };
185 
186 /*
187  * Scheduling classes.
188  */
189 static int mod_infosched(struct modlsched *, struct modlinkage *, int *);
190 static int mod_installsched(struct modlsched *, struct modlinkage *);
191 static int mod_removesched(struct modlsched *, struct modlinkage *);
192 
193 struct mod_ops mod_schedops = {
194 	mod_installsched, mod_removesched, mod_infosched
195 };
196 
197 /*
198  * Exec file type (like ELF, ...).
199  */
200 static int mod_infoexec(struct modlexec *, struct modlinkage *, int *);
201 static int mod_installexec(struct modlexec *, struct modlinkage *);
202 static int mod_removeexec(struct modlexec *, struct modlinkage *);
203 
204 struct mod_ops mod_execops = {
205 	mod_installexec, mod_removeexec, mod_infoexec
206 };
207 
208 /*
209  * Dacf (Dynamic Autoconfiguration) modules.
210  */
211 static int mod_infodacf(struct modldacf *, struct modlinkage *, int *);
212 static int mod_installdacf(struct modldacf *, struct modlinkage *);
213 static int mod_removedacf(struct modldacf *, struct modlinkage *);
214 
215 struct mod_ops mod_dacfops = {
216 	mod_installdacf, mod_removedacf, mod_infodacf
217 };
218 
219 /*
220  * /dev fs modules
221  */
222 static int mod_infodev(struct modldev *, struct modlinkage *, int *);
223 static int mod_installdev(struct modldev *, struct modlinkage *);
224 static int mod_removedev(struct modldev *, struct modlinkage *);
225 
226 struct mod_ops mod_devfsops = {
227 	mod_installdev, mod_removedev, mod_infodev
228 };
229 
230 /*
231  * PCBE (Performance Counter BackEnd) modules.
232  */
233 static int mod_installpcbe(struct modlpcbe *, struct modlinkage *);
234 static int mod_removepcbe(struct modlpcbe *, struct modlinkage *);
235 
236 struct mod_ops mod_pcbeops = {
237 	mod_installpcbe, mod_removepcbe, mod_infonull
238 };
239 
240 static struct sysent *mod_getsysent(struct modlinkage *, struct sysent *);
241 
242 static char uninstall_err[] = "Cannot uninstall %s; not installed";
243 
244 /*
245  * Debugging support
246  */
247 #define	DRV_DBG		MODDEBUG_LOADMSG2
248 
249 /*PRINTFLIKE2*/
250 static void mod_dprintf(int flag, const char *format, ...) __KPRINTFLIKE(2);
251 
252 static void
253 mod_dprintf(int flag, const char *format, ...)
254 {
255 	va_list alist;
256 
257 	if ((moddebug & flag) != 0) {
258 		va_start(alist, format);
259 		(void) vprintf(format, alist);
260 		va_end(alist);
261 	}
262 }
263 
264 /*
265  * Install a module.
266  * (This routine is in the Solaris SPARC DDI/DKI)
267  */
268 int
269 mod_install(struct modlinkage *modlp)
270 {
271 	int retval = -1;	/* No linkage structures */
272 	struct modlmisc **linkpp;
273 	struct modlmisc **linkpp1;
274 
275 	if (modlp->ml_rev != MODREV_1) {
276 		printf("mod_install:  modlinkage structure is not MODREV_1\n");
277 		return (EINVAL);
278 	}
279 	linkpp = (struct modlmisc **)&modlp->ml_linkage[0];
280 
281 	while (*linkpp != NULL) {
282 		if ((retval = MODL_INSTALL(*linkpp, modlp)) != 0) {
283 			linkpp1 = (struct modlmisc **)&modlp->ml_linkage[0];
284 
285 			while (linkpp1 != linkpp) {
286 				MODL_REMOVE(*linkpp1, modlp); /* clean up */
287 				linkpp1++;
288 			}
289 			break;
290 		}
291 		linkpp++;
292 	}
293 	return (retval);
294 }
295 
296 static char *reins_err =
297 	"Could not reinstall %s\nReboot to correct the problem";
298 
299 /*
300  * Remove a module.  This is called by the module wrapper routine.
301  * (This routine is in the Solaris SPARC DDI/DKI)
302  */
303 int
304 mod_remove(struct modlinkage *modlp)
305 {
306 	int retval = 0;
307 	struct modlmisc **linkpp, *last_linkp;
308 
309 	linkpp = (struct modlmisc **)&modlp->ml_linkage[0];
310 
311 	while (*linkpp != NULL) {
312 		if ((retval = MODL_REMOVE(*linkpp, modlp)) != 0) {
313 			last_linkp = *linkpp;
314 			linkpp = (struct modlmisc **)&modlp->ml_linkage[0];
315 			while (*linkpp != last_linkp) {
316 				if (MODL_INSTALL(*linkpp, modlp) != 0) {
317 					cmn_err(CE_WARN, reins_err,
318 						(*linkpp)->misc_linkinfo);
319 					break;
320 				}
321 				linkpp++;
322 			}
323 			break;
324 		}
325 		linkpp++;
326 	}
327 	return (retval);
328 }
329 
330 /*
331  * Get module status.
332  * (This routine is in the Solaris SPARC DDI/DKI)
333  */
334 int
335 mod_info(struct modlinkage *modlp, struct modinfo *modinfop)
336 {
337 	int i;
338 	int retval = 0;
339 	struct modspecific_info *msip;
340 	struct modlmisc **linkpp;
341 
342 	modinfop->mi_rev = modlp->ml_rev;
343 
344 	linkpp = (struct modlmisc **)modlp->ml_linkage;
345 	msip = &modinfop->mi_msinfo[0];
346 
347 	for (i = 0; i < MODMAXLINK; i++) {
348 		if (*linkpp == NULL) {
349 			msip->msi_linkinfo[0] = '\0';
350 		} else {
351 			(void) strncpy(msip->msi_linkinfo,
352 			    (*linkpp)->misc_linkinfo, MODMAXLINKINFOLEN);
353 			retval = MODL_INFO(*linkpp, modlp, &msip->msi_p0);
354 			if (retval != 0)
355 				break;
356 			linkpp++;
357 		}
358 		msip++;
359 	}
360 
361 	if (modinfop->mi_info == MI_INFO_LINKAGE) {
362 		/*
363 		 * Slight kludge used to extract the address of the
364 		 * modlinkage structure from the module (just after
365 		 * loading a module for the very first time)
366 		 */
367 		modinfop->mi_base = (void *)modlp;
368 	}
369 
370 	if (retval == 0)
371 		return (1);
372 	return (0);
373 }
374 
375 /*
376  * Get module name.
377  */
378 char *
379 mod_modname(struct modlinkage *modlp)
380 {
381 	struct modctl	*mcp;
382 
383 	if ((mcp = mod_getctl(modlp)) == NULL)
384 		return (NULL);
385 
386 	return (mcp->mod_modname);
387 }
388 
389 /*
390  * Null operation; return 0.
391  */
392 /*ARGSUSED*/
393 static int
394 mod_null(struct modldrv *modl, struct modlinkage *modlp)
395 {
396 	return (0);
397 }
398 
399 /*
400  * Status for User modules.
401  */
402 /*ARGSUSED*/
403 static int
404 mod_infonull(void *modl, struct modlinkage *modlp, int *p0)
405 {
406 	*p0 = -1;		/* for modinfo display */
407 	return (0);
408 }
409 
410 /*
411  * Driver status info
412  */
413 /*ARGSUSED*/
414 static int
415 mod_infodrv(struct modldrv *modl, struct modlinkage *modlp, int *p0)
416 {
417 	struct modctl *mcp;
418 	char *mod_name;
419 
420 	if ((mcp = mod_getctl(modlp)) == NULL) {
421 		*p0 = -1;
422 		return (0);	/* driver is not yet installed */
423 	}
424 
425 	mod_name = mcp->mod_modname;
426 
427 	*p0 = ddi_name_to_major(mod_name);
428 	return (0);
429 }
430 
431 /*
432  * Manage dacf (device autoconfiguration) modules
433  */
434 
435 /*ARGSUSED*/
436 static int
437 mod_infodacf(struct modldacf *modl, struct modlinkage *modlp, int *p0)
438 {
439 	if (mod_getctl(modlp) == NULL) {
440 		*p0 = -1;
441 		return (0);	/* module is not yet installed */
442 	}
443 
444 	*p0 = 0;
445 	return (0);
446 }
447 
448 static int
449 mod_installdacf(struct modldacf *modl, struct modlinkage *modlp)
450 {
451 	struct modctl	*mcp;
452 
453 	if ((mcp = mod_getctl(modlp)) == NULL)
454 		return (EINVAL);
455 	return (dacf_module_register(mcp->mod_modname, modl->dacf_dacfsw));
456 }
457 
458 /*ARGSUSED*/
459 static int
460 mod_removedacf(struct modldacf *modl, struct modlinkage *modlp)
461 {
462 	struct modctl	*mcp;
463 
464 	if ((mcp = mod_getctl(modlp)) == NULL)
465 		return (EINVAL);
466 	return (dacf_module_unregister(mcp->mod_modname));
467 }
468 
469 /*
470  * Manage PCBE (Performance Counter BackEnd) modules.
471  */
472 /*ARGSUSED*/
473 static int
474 mod_installpcbe(struct modlpcbe *modl, struct modlinkage *modlp)
475 {
476 	if (modl->pcbe_ops->pcbe_ver != PCBE_VER_1) {
477 		cmn_err(CE_WARN, "pcbe '%s' version mismatch",
478 		    modl->pcbe_linkinfo);
479 		return (EINVAL);
480 	}
481 
482 	kcpc_register_pcbe(modl->pcbe_ops);
483 	return (0);
484 }
485 
486 /*
487  * PCBEs may not be unloaded. It would make CPC locking too complex, and since
488  * PCBEs are loaded once and used for life, there is no harm done in leaving
489  * them in the system.
490  */
491 /*ARGSUSED*/
492 static int
493 mod_removepcbe(struct modlpcbe *modl, struct modlinkage *modlp)
494 {
495 	return (EBUSY);
496 }
497 
498 /*
499  * manage /dev fs modules
500  */
501 /*ARGSUSED*/
502 static int
503 mod_infodev(struct modldev *modl, struct modlinkage *modlp, int *p0)
504 {
505 	if (mod_getctl(modlp) == NULL) {
506 		*p0 = -1;
507 		return (0);	/* module is not yet installed */
508 	}
509 
510 	*p0 = 0;
511 	return (0);
512 }
513 
514 static int
515 mod_installdev(struct modldev *modl, struct modlinkage *modlp)
516 {
517 	struct modctl	*mcp;
518 
519 	if ((mcp = mod_getctl(modlp)) == NULL)
520 		return (EINVAL);
521 	return (sdev_module_register(mcp->mod_modname, modl->dev_ops));
522 }
523 
524 /*
525  * /dev modules are not unloadable.
526  */
527 /*ARGSUSED*/
528 static int
529 mod_removedev(struct modldev *modl, struct modlinkage *modlp)
530 {
531 	return (EBUSY);
532 }
533 
534 /*
535  * Install a new driver
536  */
537 static int
538 mod_installdrv(struct modldrv *modl, struct modlinkage *modlp)
539 {
540 	struct modctl *mcp;
541 	struct dev_ops *ops;
542 	char *modname;
543 	major_t major;
544 	struct dev_ops *dp;
545 	struct devnames *dnp;
546 	struct streamtab *str;
547 	cdevsw_impl_t *cdp;
548 	uint_t sqtype;
549 	uint_t qflag;
550 	uint_t flag;
551 	int err = 0;
552 
553 	/* sanity check module */
554 	if ((mcp = mod_getctl(modlp)) == NULL) {
555 		cmn_err(CE_WARN, "mod_install: bad module linkage data");
556 		err = ENXIO;
557 		goto done;
558 	}
559 	modname = mcp->mod_modname;
560 
561 	/* Sanity check modname */
562 	if ((major = ddi_name_to_major(modname)) == (major_t)-1) {
563 #ifdef DEBUG
564 		cmn_err(CE_WARN,
565 		    "mod_installdrv: no major number for %s", modname);
566 #endif
567 		err = ENXIO;
568 		goto done;
569 	}
570 
571 	/* Verify MP safety flag */
572 	ops = modl->drv_dev_ops;
573 	if (ops->devo_bus_ops == NULL && ops->devo_cb_ops != NULL &&
574 	    !(ops->devo_cb_ops->cb_flag & D_MP)) {
575 		cmn_err(CE_WARN,
576 		    "mod_installdrv: MT-unsafe driver '%s' rejected", modname);
577 		err = ENXIO;
578 		goto done;
579 	}
580 
581 
582 	/* Is bus_map_fault signature correct (version 8 and higher)? */
583 	if (ops->devo_bus_ops != NULL &&
584 	    ops->devo_bus_ops->bus_map_fault != NULL &&
585 	    ops->devo_bus_ops->bus_map_fault != i_ddi_map_fault &&
586 	    ops->devo_bus_ops->busops_rev < BUSO_REV_8) {
587 
588 		cmn_err(CE_WARN,
589 		    "mod_installdrv: busops' revision of '%s' is too low"
590 		    " (must be at least 8)", modname);
591 		err = ENXIO;
592 		goto done;
593 	}
594 
595 
596 	/* Make sure the driver is uninstalled */
597 	dnp = &devnamesp[major];
598 	LOCK_DEV_OPS(&dnp->dn_lock);
599 	dp = devopsp[major];
600 
601 	if (dnp->dn_flags & DN_DRIVER_REMOVED) {
602 #ifdef DEBUG
603 		cmn_err(CE_NOTE,
604 		    "mod_installdrv: driver has been removed %s", modname);
605 #endif
606 		err = ENXIO;
607 		goto unlock;
608 	}
609 
610 	if (dp != &nodev_ops && dp != &mod_nodev_ops) {
611 		cmn_err(CE_WARN,
612 		    "mod_installdrv: driver already installed %s", modname);
613 		err = EALREADY;
614 		goto unlock;
615 	}
616 
617 	devopsp[major] = ops; /* setup devopsp */
618 
619 	if ((str = STREAMSTAB(major)) != NULL) {	/* streams driver */
620 		flag = CBFLAG(major);
621 		if ((err = devflg_to_qflag(str, flag, &qflag, &sqtype)) != 0)
622 			goto unlock;
623 		cdp = &devimpl[major];
624 		ASSERT(cdp->d_str == NULL);
625 		cdp->d_str = str;
626 		cdp->d_qflag = qflag | QISDRV;
627 		cdp->d_sqtype = sqtype;
628 	}
629 
630 	if (ops->devo_bus_ops == NULL)
631 		dnp->dn_flags |= DN_LEAF_DRIVER;
632 
633 unlock:
634 	UNLOCK_DEV_OPS(&dnp->dn_lock);
635 done:
636 	return (err);
637 }
638 
639 static int
640 mod_removedrv(struct modldrv *modl, struct modlinkage *modlp)
641 {
642 	struct modctl *mcp;
643 	struct dev_ops *ops;
644 	struct devnames *dnp;
645 	struct dev_ops *dp;
646 	major_t major;
647 	char *modname;
648 	extern kthread_id_t mod_aul_thread;
649 	struct streamtab *str;
650 	cdevsw_impl_t *cdp;
651 	int err = 0;
652 
653 	/* Don't auto unload modules on if moddebug flag is set */
654 	if ((moddebug & MODDEBUG_NOAUL_DRV) && (mod_aul_thread == curthread)) {
655 		err = EBUSY;
656 		goto done;
657 	}
658 
659 	/* Verify modname has a driver major */
660 	mcp = mod_getctl(modlp);
661 	ASSERT(mcp != NULL);
662 	modname = mcp->mod_modname;
663 
664 	if ((major = ddi_name_to_major(modname)) == -1) {
665 		cmn_err(CE_WARN, uninstall_err, modname);
666 		err = EINVAL;
667 		goto done;
668 	}
669 
670 	ops = modl->drv_dev_ops;
671 	dnp = &(devnamesp[major]);
672 	LOCK_DEV_OPS(&(dnp->dn_lock));
673 
674 	dp = devopsp[major];
675 
676 	if (dp != ops)  {
677 		cmn_err(CE_NOTE, "mod_removedrv: mismatched driver for %s",
678 		    modname);
679 		err = EBUSY;
680 		goto unlock;
681 	}
682 
683 	/*
684 	 * A driver is not unloadable if its dev_ops are held
685 	 */
686 	if (!DRV_UNLOADABLE(dp)) {
687 		mod_dprintf(DRV_DBG, "Cannot unload device driver <%s>,"
688 		    " refcnt %d\n", modname, dp->devo_refcnt);
689 		err = EBUSY;
690 		goto unlock;
691 	}
692 
693 	/*
694 	 * OK to unload.
695 	 */
696 	if ((str = STREAMSTAB(major)) != NULL) {	/* streams driver */
697 		cdp = &devimpl[major];
698 		ASSERT(cdp->d_str == str);
699 		cdp->d_str = NULL;
700 
701 		/* check for reference to per-dev syncq */
702 		if (cdp->d_dmp != NULL) {
703 			rele_dm(cdp->d_dmp);
704 			cdp->d_dmp = NULL;
705 		}
706 	}
707 
708 	devopsp[major] = &mod_nodev_ops;
709 	dnp->dn_flags &= ~(DN_DRIVER_HELD|DN_NO_AUTODETACH);
710 
711 unlock:
712 	UNLOCK_DEV_OPS(&(dnp->dn_lock));
713 done:
714 	return (err);
715 }
716 
717 /*
718  * System call subroutines
719  */
720 
721 /*
722  * Compute system call number for given sysent and sysent table
723  */
724 static int
725 mod_infosysnum(struct modlinkage *modlp, struct sysent table[])
726 {
727 	struct sysent *sysp;
728 
729 	if ((sysp = mod_getsysent(modlp, table)) == NULL)
730 		return (-1);
731 	return ((int)(sysp - table));
732 }
733 
734 /*
735  * Put a loadable system call entry into a sysent table.
736  */
737 static int
738 mod_installsys_sysent(
739 	struct modlsys		*modl,
740 	struct modlinkage	*modlp,
741 	struct sysent		table[])
742 {
743 	struct sysent *sysp;
744 	struct sysent *mp;
745 
746 #ifdef DEBUG
747 	/*
748 	 * Before we even play with the sysent table, sanity check the
749 	 * incoming flags to make sure the entry is valid
750 	 */
751 	switch (modl->sys_sysent->sy_flags & SE_RVAL_MASK) {
752 	case SE_32RVAL1:
753 		/* only r_val1 returned */
754 	case SE_32RVAL1 | SE_32RVAL2:
755 		/* r_val1 and r_val2 returned */
756 	case SE_64RVAL:
757 		/* 64-bit rval returned */
758 		break;
759 	default:
760 		cmn_err(CE_WARN, "loadable syscall: %p: bad rval flags %x",
761 		    (void *)modl, modl->sys_sysent->sy_flags);
762 		return (ENOSYS);
763 	}
764 #endif
765 	if ((sysp = mod_getsysent(modlp, table)) == NULL)
766 		return (ENOSPC);
767 
768 	/*
769 	 * We should only block here until the reader in syscall gives
770 	 * up the lock.  Multiple writers are prevented in the mod layer.
771 	 */
772 	rw_enter(sysp->sy_lock, RW_WRITER);
773 	mp = modl->sys_sysent;
774 	sysp->sy_narg = mp->sy_narg;
775 	sysp->sy_call = mp->sy_call;
776 
777 	/*
778 	 * clear the old call method flag, and get the new one from the module.
779 	 */
780 	sysp->sy_flags &= ~SE_ARGC;
781 	sysp->sy_flags |= SE_LOADED |
782 	    (mp->sy_flags & (SE_ARGC | SE_NOUNLOAD | SE_RVAL_MASK));
783 
784 	/*
785 	 * If the syscall doesn't need or want unloading, it can avoid
786 	 * the locking overhead on each entry.  Convert the sysent to a
787 	 * normal non-loadable entry in that case.
788 	 */
789 	if (mp->sy_flags & SE_NOUNLOAD) {
790 		if (mp->sy_flags & SE_ARGC) {
791 			sysp->sy_callc = (int64_t (*)())mp->sy_call;
792 		} else {
793 			sysp->sy_callc = syscall_ap;
794 		}
795 		sysp->sy_flags &= ~SE_LOADABLE;
796 	}
797 	rw_exit(sysp->sy_lock);
798 	return (0);
799 }
800 
801 /*
802  * Remove a loadable system call entry from a sysent table.
803  */
804 static int
805 mod_removesys_sysent(
806 	struct modlsys		*modl,
807 	struct modlinkage	*modlp,
808 	struct sysent		table[])
809 {
810 	struct sysent	*sysp;
811 
812 	if ((sysp = mod_getsysent(modlp, table)) == NULL ||
813 	    (sysp->sy_flags & (SE_LOADABLE | SE_NOUNLOAD)) == 0 ||
814 	    sysp->sy_call != modl->sys_sysent->sy_call) {
815 
816 		struct modctl *mcp = mod_getctl(modlp);
817 		char *modname = mcp->mod_modname;
818 
819 		cmn_err(CE_WARN, uninstall_err, modname);
820 		return (EINVAL);
821 	}
822 
823 	/* If we can't get the write lock, we can't unlink from the system */
824 
825 	if (!(moddebug & MODDEBUG_NOAUL_SYS) &&
826 	    rw_tryenter(sysp->sy_lock, RW_WRITER)) {
827 		/*
828 		 * Check the flags to be sure the syscall is still
829 		 * (un)loadable.
830 		 * If SE_NOUNLOAD is set, SE_LOADABLE will not be.
831 		 */
832 		if ((sysp->sy_flags & (SE_LOADED | SE_LOADABLE)) ==
833 		    (SE_LOADED | SE_LOADABLE)) {
834 			sysp->sy_flags &= ~SE_LOADED;
835 			sysp->sy_callc = loadable_syscall;
836 			sysp->sy_call = (int (*)())nosys;
837 			rw_exit(sysp->sy_lock);
838 			return (0);
839 		}
840 		rw_exit(sysp->sy_lock);
841 	}
842 	return (EBUSY);
843 }
844 
845 /*
846  * System call status info
847  */
848 /*ARGSUSED*/
849 static int
850 mod_infosys(struct modlsys *modl, struct modlinkage *modlp, int *p0)
851 {
852 	*p0 = mod_infosysnum(modlp, sysent);
853 	return (0);
854 }
855 
856 /*
857  * Link a system call into the system by setting the proper sysent entry.
858  * Called from the module's _init routine.
859  */
860 static int
861 mod_installsys(struct modlsys *modl, struct modlinkage *modlp)
862 {
863 	return (mod_installsys_sysent(modl, modlp, sysent));
864 }
865 
866 /*
867  * Unlink a system call from the system.
868  * Called from a modules _fini routine.
869  */
870 static int
871 mod_removesys(struct modlsys *modl, struct modlinkage *modlp)
872 {
873 	return (mod_removesys_sysent(modl, modlp, sysent));
874 }
875 
876 #ifdef _SYSCALL32_IMPL
877 
878 /*
879  * 32-bit system call status info
880  */
881 /*ARGSUSED*/
882 static int
883 mod_infosys32(struct modlsys *modl, struct modlinkage *modlp, int *p0)
884 {
885 	*p0 = mod_infosysnum(modlp, sysent32);
886 	return (0);
887 }
888 
889 /*
890  * Link the 32-bit syscall into the system by setting the proper sysent entry.
891  * Also called from the module's _init routine.
892  */
893 static int
894 mod_installsys32(struct modlsys *modl, struct modlinkage *modlp)
895 {
896 	return (mod_installsys_sysent(modl, modlp, sysent32));
897 }
898 
899 /*
900  * Unlink the 32-bit flavor of a system call from the system.
901  * Also called from a module's _fini routine.
902  */
903 static int
904 mod_removesys32(struct modlsys *modl, struct modlinkage *modlp)
905 {
906 	return (mod_removesys_sysent(modl, modlp, sysent32));
907 }
908 
909 #endif	/* _SYSCALL32_IMPL */
910 
911 /*
912  * Filesystem status info
913  */
914 /*ARGSUSED*/
915 static int
916 mod_infofs(struct modlfs *modl, struct modlinkage *modlp, int *p0)
917 {
918 	struct vfssw *vswp;
919 
920 	RLOCK_VFSSW();
921 	if ((vswp = vfs_getvfsswbyname(modl->fs_vfsdef->name)) == NULL)
922 		*p0 = -1;
923 	else {
924 		*p0 = vswp - vfssw;
925 		vfs_unrefvfssw(vswp);
926 	}
927 	RUNLOCK_VFSSW();
928 	return (0);
929 }
930 
931 /*
932  * Install a filesystem.
933  */
934 /*ARGSUSED1*/
935 static int
936 mod_installfs(struct modlfs *modl, struct modlinkage *modlp)
937 {
938 	struct vfssw *vswp;
939 	struct modctl *mcp;
940 	char *fsname;
941 	char ksname[KSTAT_STRLEN + 1];
942 	int fstype;	/* index into vfssw[] and vsanchor_fstype[] */
943 	int allocated;
944 	int err;
945 	int vsw_stats_enabled;
946 	/* Not for public consumption so these aren't in a header file */
947 	extern int	vopstats_enabled;
948 	extern vopstats_t **vopstats_fstype;
949 	extern kstat_t *new_vskstat(char *, vopstats_t *);
950 	extern void initialize_vopstats(vopstats_t *);
951 
952 	if (modl->fs_vfsdef->def_version == VFSDEF_VERSION) {
953 		/* Version matched */
954 		fsname = modl->fs_vfsdef->name;
955 	} else {
956 		if ((modl->fs_vfsdef->def_version > 0) &&
957 		    (modl->fs_vfsdef->def_version < VFSDEF_VERSION)) {
958 			/* Older VFSDEF_VERSION */
959 			fsname = modl->fs_vfsdef->name;
960 		} else if ((mcp = mod_getctl(modlp)) != NULL) {
961 			/* Pre-VFSDEF_VERSION */
962 			fsname = mcp->mod_modname;
963 		} else {
964 			/* If all else fails... */
965 			fsname = "<unknown file system type>";
966 		}
967 
968 		cmn_err(CE_WARN, "file system '%s' version mismatch", fsname);
969 		return (ENXIO);
970 	}
971 
972 	allocated = 0;
973 
974 	WLOCK_VFSSW();
975 	if ((vswp = vfs_getvfsswbyname(fsname)) == NULL) {
976 		if ((vswp = allocate_vfssw(fsname)) == NULL) {
977 			WUNLOCK_VFSSW();
978 			/*
979 			 * See 1095689.  If this message appears, then
980 			 * we either need to make the vfssw table bigger
981 			 * statically, or make it grow dynamically.
982 			 */
983 			cmn_err(CE_WARN, "no room for '%s' in vfssw!", fsname);
984 			return (ENXIO);
985 		}
986 		allocated = 1;
987 	}
988 	ASSERT(vswp != NULL);
989 
990 	fstype = vswp - vfssw;	/* Pointer arithmetic to get the fstype */
991 
992 	/* Turn on everything by default *except* VSW_STATS */
993 	vswp->vsw_flag = modl->fs_vfsdef->flags & ~(VSW_STATS);
994 
995 	if (modl->fs_vfsdef->flags & VSW_HASPROTO) {
996 		vfs_mergeopttbl(&vfs_mntopts, modl->fs_vfsdef->optproto,
997 		    &vswp->vsw_optproto);
998 	} else {
999 		vfs_copyopttbl(&vfs_mntopts, &vswp->vsw_optproto);
1000 	}
1001 
1002 	if (modl->fs_vfsdef->flags & VSW_CANRWRO) {
1003 		/*
1004 		 * This obviously implies VSW_CANREMOUNT.
1005 		 */
1006 		vswp->vsw_flag |= VSW_CANREMOUNT;
1007 	}
1008 
1009 	/*
1010 	 * If stats are enabled system wide and for this fstype, then
1011 	 * set the VSW_STATS flag in the proper vfssw[] table entry.
1012 	 */
1013 	if (vopstats_enabled && modl->fs_vfsdef->flags & VSW_STATS) {
1014 		vswp->vsw_flag |= VSW_STATS;
1015 	}
1016 
1017 	if (modl->fs_vfsdef->init == NULL)
1018 		err = EFAULT;
1019 	else
1020 		err = (*(modl->fs_vfsdef->init))(fstype, fsname);
1021 
1022 	if (err != 0) {
1023 		if (allocated) {
1024 			kmem_free(vswp->vsw_name, strlen(vswp->vsw_name)+1);
1025 			vswp->vsw_name = "";
1026 		}
1027 		vswp->vsw_flag = 0;
1028 		vswp->vsw_init = NULL;
1029 	}
1030 
1031 	/* We don't want to hold the vfssw[] write lock over a kmem_alloc() */
1032 	vsw_stats_enabled = vswp->vsw_flag & VSW_STATS;
1033 
1034 	vfs_unrefvfssw(vswp);
1035 	WUNLOCK_VFSSW();
1036 
1037 	/* If everything is on, set up the per-fstype vopstats */
1038 	if (vsw_stats_enabled && vopstats_enabled &&
1039 	    vopstats_fstype && vopstats_fstype[fstype] == NULL) {
1040 		(void) strlcpy(ksname, VOPSTATS_STR, sizeof (ksname));
1041 		(void) strlcat(ksname, vfssw[fstype].vsw_name, sizeof (ksname));
1042 		vopstats_fstype[fstype] =
1043 		    kmem_alloc(sizeof (vopstats_t), KM_SLEEP);
1044 		initialize_vopstats(vopstats_fstype[fstype]);
1045 		(void) new_vskstat(ksname, vopstats_fstype[fstype]);
1046 	}
1047 	return (err);
1048 }
1049 
1050 /*
1051  * Remove a filesystem
1052  */
1053 static int
1054 mod_removefs(struct modlfs *modl, struct modlinkage *modlp)
1055 {
1056 	struct vfssw *vswp;
1057 	struct modctl *mcp;
1058 	char *modname;
1059 
1060 	if (moddebug & MODDEBUG_NOAUL_FS)
1061 		return (EBUSY);
1062 
1063 	WLOCK_VFSSW();
1064 	if ((vswp = vfs_getvfsswbyname(modl->fs_vfsdef->name)) == NULL) {
1065 		mcp = mod_getctl(modlp);
1066 		ASSERT(mcp != NULL);
1067 		modname = mcp->mod_modname;
1068 		WUNLOCK_VFSSW();
1069 		cmn_err(CE_WARN, uninstall_err, modname);
1070 		return (EINVAL);
1071 	}
1072 	if (vswp->vsw_count != 1) {
1073 		vfs_unrefvfssw(vswp);
1074 		WUNLOCK_VFSSW();
1075 		return (EBUSY);
1076 	}
1077 
1078 	/* XXX - Shouldn't the refcount be sufficient? */
1079 
1080 	if (vfs_opsinuse(&vswp->vsw_vfsops)) {
1081 		vfs_unrefvfssw(vswp);
1082 		WUNLOCK_VFSSW();
1083 		return (EBUSY);
1084 	}
1085 
1086 	vfs_freeopttbl(&vswp->vsw_optproto);
1087 	vswp->vsw_optproto.mo_count = 0;
1088 
1089 	vswp->vsw_flag = 0;
1090 	vswp->vsw_init = NULL;
1091 	vfs_unrefvfssw(vswp);
1092 	WUNLOCK_VFSSW();
1093 	return (0);
1094 }
1095 
1096 /*
1097  * Get status of a streams module.
1098  */
1099 /*ARGSUSED*/
1100 static int
1101 mod_infostrmod(struct modlstrmod *modl, struct modlinkage *modlp, int *p0)
1102 {
1103 	*p0 = -1;	/* no useful info */
1104 	return (0);
1105 }
1106 
1107 
1108 /*
1109  * Install a streams module.
1110  */
1111 /*ARGSUSED*/
1112 static int
1113 mod_installstrmod(struct modlstrmod *modl, struct modlinkage *modlp)
1114 {
1115 	struct fmodsw *fp = modl->strmod_fmodsw;
1116 
1117 	if (!(fp->f_flag & D_MP)) {
1118 		cmn_err(CE_WARN, "mod_install: MT-unsafe strmod '%s' rejected",
1119 		    fp->f_name);
1120 		return (ENXIO);
1121 	}
1122 
1123 	return (fmodsw_register(fp->f_name, fp->f_str, fp->f_flag));
1124 }
1125 
1126 /*
1127  * Remove a streams module.
1128  */
1129 /*ARGSUSED*/
1130 static int
1131 mod_removestrmod(struct modlstrmod *modl, struct modlinkage *modlp)
1132 {
1133 	if (moddebug & MODDEBUG_NOAUL_STR)
1134 		return (EBUSY);
1135 
1136 	return (fmodsw_unregister(modl->strmod_fmodsw->f_name));
1137 }
1138 
1139 /*
1140  * Get status of a scheduling class module.
1141  */
1142 /*ARGSUSED1*/
1143 static int
1144 mod_infosched(struct modlsched *modl, struct modlinkage *modlp, int *p0)
1145 {
1146 	int	status;
1147 	auto id_t	cid;
1148 
1149 	status = getcidbyname(modl->sched_class->cl_name, &cid);
1150 
1151 	if (status != 0)
1152 		*p0 = -1;
1153 	else
1154 		*p0 = cid;
1155 
1156 	return (0);
1157 }
1158 
1159 /*
1160  * Install a scheduling class module.
1161  */
1162 /*ARGSUSED1*/
1163 static int
1164 mod_installsched(struct modlsched *modl, struct modlinkage *modlp)
1165 {
1166 	sclass_t *clp;
1167 	int status;
1168 	id_t cid;
1169 
1170 	/*
1171 	 * See if module is already installed.
1172 	 */
1173 	mutex_enter(&class_lock);
1174 	status = alloc_cid(modl->sched_class->cl_name, &cid);
1175 	mutex_exit(&class_lock);
1176 	ASSERT(status == 0);
1177 	clp = &sclass[cid];
1178 	rw_enter(clp->cl_lock, RW_WRITER);
1179 	if (SCHED_INSTALLED(clp)) {
1180 		printf("scheduling class %s is already installed\n",
1181 			modl->sched_class->cl_name);
1182 		rw_exit(clp->cl_lock);
1183 		return (EBUSY);		/* it's already there */
1184 	}
1185 
1186 	clp->cl_init = modl->sched_class->cl_init;
1187 	clp->cl_funcs = modl->sched_class->cl_funcs;
1188 	modl->sched_class = clp;
1189 	disp_add(clp);
1190 	loaded_classes++;		/* for priocntl system call */
1191 	rw_exit(clp->cl_lock);
1192 	return (0);
1193 }
1194 
1195 /*
1196  * Remove a scheduling class module.
1197  *
1198  * we only null out the init func and the class functions because
1199  * once a class has been loaded it has that slot in the class
1200  * array until the next reboot. We don't decrement loaded_classes
1201  * because this keeps count of the number of classes that have
1202  * been loaded for this session. It will have to be this way until
1203  * we implement the class array as a linked list and do true
1204  * dynamic allocation.
1205  */
1206 static int
1207 mod_removesched(struct modlsched *modl, struct modlinkage *modlp)
1208 {
1209 	int status;
1210 	sclass_t *clp;
1211 	struct modctl *mcp;
1212 	char *modname;
1213 	id_t cid;
1214 
1215 	status = getcidbyname(modl->sched_class->cl_name, &cid);
1216 	if (status != 0) {
1217 		mcp = mod_getctl(modlp);
1218 		ASSERT(mcp != NULL);
1219 		modname = mcp->mod_modname;
1220 		cmn_err(CE_WARN, uninstall_err, modname);
1221 		return (EINVAL);
1222 	}
1223 	clp = &sclass[cid];
1224 	if (moddebug & MODDEBUG_NOAUL_SCHED ||
1225 	    !rw_tryenter(clp->cl_lock, RW_WRITER))
1226 		return (EBUSY);
1227 
1228 	clp->cl_init = NULL;
1229 	clp->cl_funcs = NULL;
1230 	rw_exit(clp->cl_lock);
1231 	return (0);
1232 }
1233 
1234 /*
1235  * Get status of an exec module.
1236  */
1237 /*ARGSUSED1*/
1238 static int
1239 mod_infoexec(struct modlexec *modl, struct modlinkage *modlp, int *p0)
1240 {
1241 	struct execsw *eswp;
1242 
1243 	if ((eswp = findexecsw(modl->exec_execsw->exec_magic)) == NULL)
1244 		*p0 = -1;
1245 	else
1246 		*p0 = eswp - execsw;
1247 
1248 	return (0);
1249 }
1250 
1251 /*
1252  * Install an exec module.
1253  */
1254 static int
1255 mod_installexec(struct modlexec *modl, struct modlinkage *modlp)
1256 {
1257 	struct execsw *eswp;
1258 	struct modctl *mcp;
1259 	char *modname;
1260 	char *magic;
1261 	size_t magic_size;
1262 
1263 	/*
1264 	 * See if execsw entry is already allocated.  Can't use findexectype()
1265 	 * because we may get a recursive call to here.
1266 	 */
1267 
1268 	if ((eswp = findexecsw(modl->exec_execsw->exec_magic)) == NULL) {
1269 		mcp = mod_getctl(modlp);
1270 		ASSERT(mcp != NULL);
1271 		modname = mcp->mod_modname;
1272 		magic = modl->exec_execsw->exec_magic;
1273 		magic_size = modl->exec_execsw->exec_maglen;
1274 		if ((eswp = allocate_execsw(modname, magic, magic_size)) ==
1275 		    NULL) {
1276 			printf("no unused entries in 'execsw'\n");
1277 			return (ENOSPC);
1278 		}
1279 	}
1280 	if (eswp->exec_func != NULL) {
1281 		printf("exec type %x is already installed\n",
1282 			*eswp->exec_magic);
1283 			return (EBUSY);		 /* it's already there! */
1284 	}
1285 
1286 	rw_enter(eswp->exec_lock, RW_WRITER);
1287 	eswp->exec_func = modl->exec_execsw->exec_func;
1288 	eswp->exec_core = modl->exec_execsw->exec_core;
1289 	rw_exit(eswp->exec_lock);
1290 
1291 	return (0);
1292 }
1293 
1294 /*
1295  * Remove an exec module.
1296  */
1297 static int
1298 mod_removeexec(struct modlexec *modl, struct modlinkage *modlp)
1299 {
1300 	struct execsw *eswp;
1301 	struct modctl *mcp;
1302 	char *modname;
1303 
1304 	eswp = findexecsw(modl->exec_execsw->exec_magic);
1305 	if (eswp == NULL) {
1306 		mcp = mod_getctl(modlp);
1307 		ASSERT(mcp != NULL);
1308 		modname = mcp->mod_modname;
1309 		cmn_err(CE_WARN, uninstall_err, modname);
1310 		return (EINVAL);
1311 	}
1312 	if (moddebug & MODDEBUG_NOAUL_EXEC ||
1313 	    !rw_tryenter(eswp->exec_lock, RW_WRITER))
1314 		return (EBUSY);
1315 	eswp->exec_func = NULL;
1316 	eswp->exec_core = NULL;
1317 	rw_exit(eswp->exec_lock);
1318 	return (0);
1319 }
1320 
1321 /*
1322  * Find a free sysent entry or check if the specified one is free.
1323  */
1324 static struct sysent *
1325 mod_getsysent(struct modlinkage *modlp, struct sysent *se)
1326 {
1327 	int sysnum;
1328 	struct modctl *mcp;
1329 	char *mod_name;
1330 
1331 	if ((mcp = mod_getctl(modlp)) == NULL) {
1332 		/*
1333 		 * This happens when we're looking up the module
1334 		 * pointer as part of a stub installation.  So
1335 		 * there's no need to whine at this point.
1336 		 */
1337 		return (NULL);
1338 	}
1339 
1340 	mod_name = mcp->mod_modname;
1341 
1342 	if ((sysnum = mod_getsysnum(mod_name)) == -1) {
1343 		cmn_err(CE_WARN, "system call missing from bind file");
1344 		return (NULL);
1345 	}
1346 
1347 	if (sysnum > 0 && sysnum < NSYSCALL &&
1348 	    (se[sysnum].sy_flags & (SE_LOADABLE | SE_NOUNLOAD)))
1349 		return (se + sysnum);
1350 
1351 	cmn_err(CE_WARN, "system call entry %d is already in use", sysnum);
1352 	return (NULL);
1353 }
1354 
1355 /*
1356  * IP Policy Modules.
1357  */
1358 /*ARGSUSED*/
1359 static int
1360 mod_infoipp(struct modlipp *modl, struct modlinkage *modlp, int *p0)
1361 {
1362 	struct modctl *mcp = mod_getctl(modlp);
1363 	ipp_mod_id_t mid;
1364 
1365 	if (mcp == NULL) {
1366 		*p0 = -1;
1367 		return (0);	/* module is not yet installed */
1368 	}
1369 
1370 	mid = ipp_mod_lookup(mcp->mod_modname);
1371 
1372 	*p0 = mid;
1373 	return (0);
1374 }
1375 
1376 static int
1377 mod_installipp(struct modlipp *modl, struct modlinkage *modlp)
1378 {
1379 	struct modctl *mcp = mod_getctl(modlp);
1380 
1381 	ASSERT(mcp != NULL);
1382 	return (ipp_mod_register(mcp->mod_modname, modl->ipp_ops));
1383 }
1384 
1385 /*ARGSUSED*/
1386 static int
1387 mod_removeipp(struct modlipp *modl, struct modlinkage *modlp)
1388 {
1389 	struct modctl *mcp = mod_getctl(modlp);
1390 	extern kthread_id_t mod_aul_thread;
1391 	ipp_mod_id_t mid;
1392 
1393 	ASSERT(mcp != NULL);
1394 
1395 	if ((moddebug & MODDEBUG_NOAUL_IPP) && (mod_aul_thread == curthread))
1396 		return (EBUSY);
1397 
1398 	mid = ipp_mod_lookup(mcp->mod_modname);
1399 	ASSERT(mid != IPP_MOD_INVAL);
1400 
1401 	return (ipp_mod_unregister(mid));
1402 }
1403