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