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