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 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * Copyright 2019 Joyent, Inc. 26 * Copyright 2023 Oxide Computer Company 27 */ 28 29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 30 /* All rights reserved. */ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/vmparam.h> 35 #include <sys/var.h> 36 #include <sys/cmn_err.h> 37 #include <sys/cred.h> 38 #include <sys/debug.h> 39 #include <sys/errno.h> 40 #include <sys/file.h> 41 #include <sys/inline.h> 42 #include <sys/kmem.h> 43 #include <sys/proc.h> 44 #include <sys/brand.h> 45 #include <sys/sysmacros.h> 46 #include <sys/systm.h> 47 #include <sys/vfs.h> 48 #include <sys/vnode.h> 49 #include <sys/cpuvar.h> 50 #include <sys/session.h> 51 #include <sys/signal.h> 52 #include <sys/auxv.h> 53 #include <sys/user.h> 54 #include <sys/disp.h> 55 #include <sys/class.h> 56 #include <sys/ts.h> 57 #include <sys/mman.h> 58 #include <sys/fault.h> 59 #include <sys/syscall.h> 60 #include <sys/schedctl.h> 61 #include <sys/pset.h> 62 #include <sys/old_procfs.h> 63 #include <sys/zone.h> 64 #include <sys/time.h> 65 #include <sys/msacct.h> 66 #include <vm/rm.h> 67 #include <vm/as.h> 68 #include <vm/rm.h> 69 #include <vm/seg.h> 70 #include <vm/seg_vn.h> 71 #include <sys/contract_impl.h> 72 #include <sys/ctfs_impl.h> 73 #include <sys/ctfs.h> 74 75 #if defined(__i386_COMPAT) 76 #include <sys/sysi86.h> 77 #endif 78 79 #include <fs/proc/prdata.h> 80 81 static int isprwrioctl(int); 82 static ulong_t prmaprunflags(long); 83 static long prmapsetflags(long); 84 static void prsetrun(kthread_t *, prrun_t *); 85 static int propenm(prnode_t *, caddr_t, caddr_t, int *, cred_t *); 86 extern void oprgetstatus(kthread_t *, prstatus_t *, zone_t *); 87 extern void oprgetpsinfo(proc_t *, prpsinfo_t *, kthread_t *); 88 static int oprgetmap(proc_t *, list_t *); 89 90 static int 91 prctioctl(prnode_t *pnp, int cmd, intptr_t arg, int flag, cred_t *cr) 92 { 93 int error = 0; 94 ct_kparam_t kparam; 95 ct_param_t *param = &kparam.param; 96 ct_template_t *tmpl; 97 98 if (cmd != CT_TSET && cmd != CT_TGET) 99 return (EINVAL); 100 101 error = ctparam_copyin((void *)arg, &kparam, flag, cmd); 102 if (error != 0) 103 return (error); 104 105 if ((error = prlock(pnp, ZNO)) != 0) { 106 kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 107 return (error); 108 } 109 110 tmpl = pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[pnp->pr_cttype]; 111 if (tmpl == NULL) { 112 prunlock(pnp); 113 kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 114 return (ESTALE); 115 } 116 117 if (cmd == CT_TSET) 118 error = ctmpl_set(tmpl, &kparam, cr); 119 else 120 error = ctmpl_get(tmpl, &kparam); 121 122 prunlock(pnp); 123 124 if (cmd == CT_TGET && error == 0) { 125 error = ctparam_copyout(&kparam, (void *)arg, flag); 126 } else { 127 kmem_free(kparam.ctpm_kbuf, param->ctpm_size); 128 } 129 130 return (error); 131 } 132 133 134 /* 135 * Control operations (lots). 136 */ 137 /* BEGIN CSTYLED */ 138 /*ARGSUSED*/ 139 #ifdef _SYSCALL32_IMPL 140 static int 141 prioctl64(struct vnode *vp, int cmd, intptr_t arg, int flag, cred_t *cr, 142 int *rvalp, caller_context_t *ct) 143 #else 144 int 145 prioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, cred_t *cr, 146 int *rvalp, caller_context_t *ct) 147 #endif /* _SYSCALL32_IMPL */ 148 { 149 /* END CSTYLED */ 150 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 151 caddr_t cmaddr = (caddr_t)arg; 152 proc_t *p; 153 user_t *up; 154 kthread_t *t; 155 klwp_t *lwp; 156 prnode_t *pnp = VTOP(vp); 157 prcommon_t *pcp; 158 prnode_t *xpnp = NULL; 159 int error; 160 int zdisp; 161 void *thing = NULL; 162 size_t thingsize = 0; 163 164 /* 165 * For copyin()/copyout(). 166 */ 167 union { 168 caddr_t va; 169 int signo; 170 int nice; 171 uint_t lwpid; 172 long flags; 173 prstatus_t prstat; 174 prrun_t prrun; 175 sigset_t smask; 176 siginfo_t info; 177 sysset_t prmask; 178 prgregset_t regs; 179 prfpregset_t fpregs; 180 prpsinfo_t prps; 181 sigset_t holdmask; 182 fltset_t fltmask; 183 prcred_t prcred; 184 prhusage_t prhusage; 185 prmap_t prmap; 186 auxv_t auxv[__KERN_NAUXV_IMPL]; 187 } un; 188 189 if (pnp->pr_type == PR_TMPL) 190 return (prctioctl(pnp, cmd, arg, flag, cr)); 191 192 /* 193 * Support for old /proc interface. 194 */ 195 if (pnp->pr_pidfile != NULL) { 196 ASSERT(pnp->pr_type == PR_PIDDIR); 197 vp = pnp->pr_pidfile; 198 pnp = VTOP(vp); 199 ASSERT(pnp->pr_type == PR_PIDFILE); 200 } 201 202 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE) 203 return (ENOTTY); 204 205 /* 206 * Fail ioctls which are logically "write" requests unless 207 * the user has write permission. 208 */ 209 if ((flag & FWRITE) == 0 && isprwrioctl(cmd)) 210 return (EBADF); 211 212 /* 213 * The following command is no longer supported. It was present on SPARC 214 * and would always error on other platforms. We now explicitly return 215 * ENOTSUP to make this more explicit. 216 */ 217 if (cmd == PIOCSXREG) 218 return (ENOTSUP); 219 220 /* 221 * Perform any necessary copyin() operations before 222 * locking the process. Helps avoid deadlocks and 223 * improves performance. 224 * 225 * Also, detect invalid ioctl codes here to avoid 226 * locking a process unnecessarily. 227 * 228 * Also, prepare to allocate space that will be needed below, 229 * case by case. 230 */ 231 error = 0; 232 switch (cmd) { 233 case PIOCGETPR: 234 thingsize = sizeof (proc_t); 235 break; 236 case PIOCGETU: 237 thingsize = sizeof (user_t); 238 break; 239 case PIOCSTOP: 240 case PIOCWSTOP: 241 case PIOCLWPIDS: 242 case PIOCGTRACE: 243 case PIOCGENTRY: 244 case PIOCGEXIT: 245 case PIOCSRLC: 246 case PIOCRRLC: 247 case PIOCSFORK: 248 case PIOCRFORK: 249 case PIOCGREG: 250 case PIOCGFPREG: 251 case PIOCSTATUS: 252 case PIOCLSTATUS: 253 case PIOCPSINFO: 254 case PIOCMAXSIG: 255 case PIOCGXREGSIZE: 256 break; 257 case PIOCGXREG: /* get extra registers */ 258 thingsize = prgetprxregsize(p); 259 break; 260 case PIOCACTION: 261 thingsize = (nsig-1) * sizeof (struct sigaction); 262 break; 263 case PIOCGHOLD: 264 case PIOCNMAP: 265 case PIOCMAP: 266 case PIOCGFAULT: 267 case PIOCCFAULT: 268 case PIOCCRED: 269 case PIOCGROUPS: 270 case PIOCUSAGE: 271 case PIOCLUSAGE: 272 break; 273 case PIOCOPENPD: 274 /* 275 * We will need this below. 276 * Allocate it now, before locking the process. 277 */ 278 xpnp = prgetnode(vp, PR_OPAGEDATA); 279 break; 280 case PIOCNAUXV: 281 case PIOCAUXV: 282 break; 283 284 #if defined(__x86) 285 case PIOCNLDT: 286 case PIOCLDT: 287 break; 288 #endif /* __x86 */ 289 290 #if defined(__sparc) 291 case PIOCGWIN: 292 thingsize = sizeof (gwindows_t); 293 break; 294 #endif /* __sparc */ 295 296 case PIOCOPENM: /* open mapped object for reading */ 297 if (cmaddr == NULL) 298 un.va = NULL; 299 else if (copyin(cmaddr, &un.va, sizeof (un.va))) 300 error = EFAULT; 301 break; 302 303 case PIOCRUN: /* make lwp or process runnable */ 304 if (cmaddr == NULL) 305 un.prrun.pr_flags = 0; 306 else if (copyin(cmaddr, &un.prrun, sizeof (un.prrun))) 307 error = EFAULT; 308 break; 309 310 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 311 if (copyin(cmaddr, &un.lwpid, sizeof (un.lwpid))) 312 error = EFAULT; 313 break; 314 315 case PIOCSTRACE: /* set signal trace mask */ 316 if (copyin(cmaddr, &un.smask, sizeof (un.smask))) 317 error = EFAULT; 318 break; 319 320 case PIOCSSIG: /* set current signal */ 321 if (cmaddr == NULL) 322 un.info.si_signo = 0; 323 else if (copyin(cmaddr, &un.info, sizeof (un.info))) 324 error = EFAULT; 325 break; 326 327 case PIOCKILL: /* send signal */ 328 case PIOCUNKILL: /* delete a signal */ 329 if (copyin(cmaddr, &un.signo, sizeof (un.signo))) 330 error = EFAULT; 331 break; 332 333 case PIOCNICE: /* set nice priority */ 334 if (copyin(cmaddr, &un.nice, sizeof (un.nice))) 335 error = EFAULT; 336 break; 337 338 case PIOCSENTRY: /* set syscall entry bit mask */ 339 case PIOCSEXIT: /* set syscall exit bit mask */ 340 if (copyin(cmaddr, &un.prmask, sizeof (un.prmask))) 341 error = EFAULT; 342 break; 343 344 case PIOCSET: /* set process flags */ 345 case PIOCRESET: /* reset process flags */ 346 if (copyin(cmaddr, &un.flags, sizeof (un.flags))) 347 error = EFAULT; 348 break; 349 350 case PIOCSREG: /* set general registers */ 351 if (copyin(cmaddr, un.regs, sizeof (un.regs))) 352 error = EFAULT; 353 break; 354 355 case PIOCSFPREG: /* set floating-point registers */ 356 if (copyin(cmaddr, &un.fpregs, sizeof (un.fpregs))) 357 error = EFAULT; 358 break; 359 360 case PIOCSHOLD: /* set signal-hold mask */ 361 if (copyin(cmaddr, &un.holdmask, sizeof (un.holdmask))) 362 error = EFAULT; 363 break; 364 365 case PIOCSFAULT: /* set mask of traced faults */ 366 if (copyin(cmaddr, &un.fltmask, sizeof (un.fltmask))) 367 error = EFAULT; 368 break; 369 370 default: 371 error = EINVAL; 372 break; 373 } 374 375 if (error) 376 return (error); 377 378 startover: 379 /* 380 * If we need kmem_alloc()d space then we allocate it now, before 381 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while 382 * holding the process lock leads to deadlock with the clock thread. 383 * (The clock thread wakes up the pageout daemon to free up space. 384 * If the clock thread blocks behind us and we are sleeping waiting 385 * for space, then space may never become available.) 386 */ 387 if (thingsize) { 388 ASSERT(thing == NULL); 389 thing = kmem_alloc(thingsize, KM_SLEEP); 390 } 391 392 switch (cmd) { 393 case PIOCPSINFO: 394 case PIOCGETPR: 395 case PIOCUSAGE: 396 case PIOCLUSAGE: 397 zdisp = ZYES; 398 break; 399 default: 400 zdisp = ZNO; 401 break; 402 } 403 404 if ((error = prlock(pnp, zdisp)) != 0) { 405 if (thing != NULL) 406 kmem_free(thing, thingsize); 407 if (xpnp) 408 prfreenode(xpnp); 409 return (error); 410 } 411 412 pcp = pnp->pr_common; 413 p = pcp->prc_proc; 414 ASSERT(p != NULL); 415 416 /* 417 * Choose a thread/lwp for the operation. 418 */ 419 if (zdisp == ZNO && cmd != PIOCSTOP && cmd != PIOCWSTOP) { 420 if (pnp->pr_type == PR_LWPIDFILE && cmd != PIOCLSTATUS) { 421 t = pcp->prc_thread; 422 ASSERT(t != NULL); 423 } else { 424 t = prchoose(p); /* returns locked thread */ 425 ASSERT(t != NULL); 426 thread_unlock(t); 427 } 428 lwp = ttolwp(t); 429 } 430 431 error = 0; 432 switch (cmd) { 433 434 case PIOCGETPR: /* read struct proc */ 435 { 436 proc_t *prp = thing; 437 438 *prp = *p; 439 prunlock(pnp); 440 if (copyout(prp, cmaddr, sizeof (proc_t))) 441 error = EFAULT; 442 kmem_free(prp, sizeof (proc_t)); 443 thing = NULL; 444 break; 445 } 446 447 case PIOCGETU: /* read u-area */ 448 { 449 user_t *userp = thing; 450 451 up = PTOU(p); 452 *userp = *up; 453 prunlock(pnp); 454 if (copyout(userp, cmaddr, sizeof (user_t))) 455 error = EFAULT; 456 kmem_free(userp, sizeof (user_t)); 457 thing = NULL; 458 break; 459 } 460 461 case PIOCOPENM: /* open mapped object for reading */ 462 error = propenm(pnp, cmaddr, un.va, rvalp, cr); 463 /* propenm() called prunlock(pnp) */ 464 break; 465 466 case PIOCSTOP: /* stop process or lwp from running */ 467 case PIOCWSTOP: /* wait for process or lwp to stop */ 468 /* 469 * Can't apply to a system process. 470 */ 471 if ((p->p_flag & SSYS) || p->p_as == &kas) { 472 prunlock(pnp); 473 error = EBUSY; 474 break; 475 } 476 477 if (cmd == PIOCSTOP) 478 pr_stop(pnp); 479 480 /* 481 * If an lwp is waiting for itself or its process, don't wait. 482 * The stopped lwp would never see the fact that it is stopped. 483 */ 484 if ((pnp->pr_type == PR_LWPIDFILE)? 485 (pcp->prc_thread == curthread) : (p == curproc)) { 486 if (cmd == PIOCWSTOP) 487 error = EBUSY; 488 prunlock(pnp); 489 break; 490 } 491 492 if ((error = pr_wait_stop(pnp, (time_t)0)) != 0) 493 break; /* pr_wait_stop() unlocked the process */ 494 495 if (cmaddr == NULL) 496 prunlock(pnp); 497 else { 498 /* 499 * Return process/lwp status information. 500 */ 501 t = pr_thread(pnp); /* returns locked thread */ 502 thread_unlock(t); 503 oprgetstatus(t, &un.prstat, VTOZONE(vp)); 504 prunlock(pnp); 505 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat))) 506 error = EFAULT; 507 } 508 break; 509 510 case PIOCRUN: /* make lwp or process runnable */ 511 { 512 long flags = un.prrun.pr_flags; 513 514 /* 515 * Cannot set an lwp running is it is not stopped. 516 * Also, no lwp other than the /proc agent lwp can 517 * be set running so long as the /proc agent lwp exists. 518 */ 519 if ((!ISTOPPED(t) && !VSTOPPED(t) && 520 !(t->t_proc_flag & TP_PRSTOP)) || 521 (p->p_agenttp != NULL && 522 (t != p->p_agenttp || pnp->pr_type != PR_LWPIDFILE))) { 523 prunlock(pnp); 524 error = EBUSY; 525 break; 526 } 527 528 if (flags & (PRSHOLD|PRSTRACE|PRSFAULT|PRSVADDR)) 529 prsetrun(t, &un.prrun); 530 531 error = pr_setrun(pnp, prmaprunflags(flags)); 532 533 prunlock(pnp); 534 break; 535 } 536 537 case PIOCLWPIDS: /* get array of lwp identifiers */ 538 { 539 int nlwp; 540 int Nlwp; 541 id_t *idp; 542 id_t *Bidp; 543 544 Nlwp = nlwp = p->p_lwpcnt; 545 546 if (thing && thingsize != (Nlwp+1) * sizeof (id_t)) { 547 kmem_free(thing, thingsize); 548 thing = NULL; 549 } 550 if (thing == NULL) { 551 thingsize = (Nlwp+1) * sizeof (id_t); 552 thing = kmem_alloc(thingsize, KM_NOSLEEP); 553 } 554 if (thing == NULL) { 555 prunlock(pnp); 556 goto startover; 557 } 558 559 idp = thing; 560 thing = NULL; 561 Bidp = idp; 562 if ((t = p->p_tlist) != NULL) { 563 do { 564 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 565 ASSERT(nlwp > 0); 566 --nlwp; 567 *idp++ = t->t_tid; 568 } while ((t = t->t_forw) != p->p_tlist); 569 } 570 *idp = 0; 571 ASSERT(nlwp == 0); 572 prunlock(pnp); 573 if (copyout(Bidp, cmaddr, (Nlwp+1) * sizeof (id_t))) 574 error = EFAULT; 575 kmem_free(Bidp, (Nlwp+1) * sizeof (id_t)); 576 break; 577 } 578 579 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 580 { 581 vnode_t *xvp; 582 int n; 583 584 prunlock(pnp); 585 if ((xvp = prlwpnode(pnp, un.lwpid)) == NULL) 586 error = ENOENT; 587 else if (error = fassign(&xvp, flag & (FREAD|FWRITE), &n)) { 588 VN_RELE(xvp); 589 } else 590 *rvalp = n; 591 break; 592 } 593 594 case PIOCOPENPD: /* return /proc page data file descriptor */ 595 { 596 vnode_t *xvp = PTOV(xpnp); 597 vnode_t *dp = pnp->pr_parent; 598 int n; 599 600 if (pnp->pr_type == PR_LWPIDFILE) { 601 dp = VTOP(dp)->pr_parent; 602 dp = VTOP(dp)->pr_parent; 603 } 604 ASSERT(VTOP(dp)->pr_type == PR_PIDDIR); 605 606 VN_HOLD(dp); 607 pcp = pnp->pr_pcommon; 608 xpnp->pr_ino = ptoi(pcp->prc_pid); 609 xpnp->pr_common = pcp; 610 xpnp->pr_pcommon = pcp; 611 xpnp->pr_parent = dp; 612 613 xpnp->pr_next = p->p_plist; 614 p->p_plist = xvp; 615 616 prunlock(pnp); 617 if (error = fassign(&xvp, FREAD, &n)) { 618 VN_RELE(xvp); 619 } else 620 *rvalp = n; 621 622 xpnp = NULL; 623 break; 624 } 625 626 case PIOCGTRACE: /* get signal trace mask */ 627 prassignset(&un.smask, &p->p_sigmask); 628 prunlock(pnp); 629 if (copyout(&un.smask, cmaddr, sizeof (un.smask))) 630 error = EFAULT; 631 break; 632 633 case PIOCSTRACE: /* set signal trace mask */ 634 prdelset(&un.smask, SIGKILL); 635 prassignset(&p->p_sigmask, &un.smask); 636 if (!sigisempty(&p->p_sigmask)) 637 p->p_proc_flag |= P_PR_TRACE; 638 else if (prisempty(&p->p_fltmask)) { 639 up = PTOU(p); 640 if (up->u_systrap == 0) 641 p->p_proc_flag &= ~P_PR_TRACE; 642 } 643 prunlock(pnp); 644 break; 645 646 case PIOCSSIG: /* set current signal */ 647 error = pr_setsig(pnp, &un.info); 648 prunlock(pnp); 649 if (un.info.si_signo == SIGKILL && error == 0) 650 pr_wait_die(pnp); 651 break; 652 653 case PIOCKILL: /* send signal */ 654 { 655 int sig = (int)un.signo; 656 657 error = pr_kill(pnp, sig, cr); 658 prunlock(pnp); 659 if (sig == SIGKILL && error == 0) 660 pr_wait_die(pnp); 661 break; 662 } 663 664 case PIOCUNKILL: /* delete a signal */ 665 error = pr_unkill(pnp, (int)un.signo); 666 prunlock(pnp); 667 break; 668 669 case PIOCNICE: /* set nice priority */ 670 error = pr_nice(p, (int)un.nice, cr); 671 prunlock(pnp); 672 break; 673 674 case PIOCGENTRY: /* get syscall entry bit mask */ 675 case PIOCGEXIT: /* get syscall exit bit mask */ 676 up = PTOU(p); 677 if (cmd == PIOCGENTRY) { 678 prassignset(&un.prmask, &up->u_entrymask); 679 } else { 680 prassignset(&un.prmask, &up->u_exitmask); 681 } 682 prunlock(pnp); 683 if (copyout(&un.prmask, cmaddr, sizeof (un.prmask))) 684 error = EFAULT; 685 break; 686 687 case PIOCSENTRY: /* set syscall entry bit mask */ 688 case PIOCSEXIT: /* set syscall exit bit mask */ 689 pr_setentryexit(p, &un.prmask, cmd == PIOCSENTRY); 690 prunlock(pnp); 691 break; 692 693 case PIOCSRLC: /* obsolete: set running on last /proc close */ 694 error = pr_set(p, prmapsetflags(PR_RLC)); 695 prunlock(pnp); 696 break; 697 698 case PIOCRRLC: /* obsolete: reset run-on-last-close flag */ 699 error = pr_unset(p, prmapsetflags(PR_RLC)); 700 prunlock(pnp); 701 break; 702 703 case PIOCSFORK: /* obsolete: set inherit-on-fork flag */ 704 error = pr_set(p, prmapsetflags(PR_FORK)); 705 prunlock(pnp); 706 break; 707 708 case PIOCRFORK: /* obsolete: reset inherit-on-fork flag */ 709 error = pr_unset(p, prmapsetflags(PR_FORK)); 710 prunlock(pnp); 711 break; 712 713 case PIOCSET: /* set process flags */ 714 error = pr_set(p, prmapsetflags(un.flags)); 715 prunlock(pnp); 716 break; 717 718 case PIOCRESET: /* reset process flags */ 719 error = pr_unset(p, prmapsetflags(un.flags)); 720 prunlock(pnp); 721 break; 722 723 case PIOCGREG: /* get general registers */ 724 if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 725 bzero(un.regs, sizeof (un.regs)); 726 else { 727 /* drop p_lock while touching the lwp's stack */ 728 mutex_exit(&p->p_lock); 729 prgetprregs(lwp, un.regs); 730 mutex_enter(&p->p_lock); 731 } 732 prunlock(pnp); 733 if (copyout(un.regs, cmaddr, sizeof (un.regs))) 734 error = EFAULT; 735 break; 736 737 case PIOCSREG: /* set general registers */ 738 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 739 error = EBUSY; 740 else { 741 /* drop p_lock while touching the lwp's stack */ 742 mutex_exit(&p->p_lock); 743 prsetprregs(lwp, un.regs, 0); 744 mutex_enter(&p->p_lock); 745 } 746 prunlock(pnp); 747 break; 748 749 case PIOCGFPREG: /* get floating-point registers */ 750 if (!prhasfp()) { 751 prunlock(pnp); 752 error = EINVAL; /* No FP support */ 753 break; 754 } 755 756 if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 757 bzero(&un.fpregs, sizeof (un.fpregs)); 758 else { 759 /* drop p_lock while touching the lwp's stack */ 760 mutex_exit(&p->p_lock); 761 prgetprfpregs(lwp, &un.fpregs); 762 mutex_enter(&p->p_lock); 763 } 764 prunlock(pnp); 765 if (copyout(&un.fpregs, cmaddr, sizeof (un.fpregs))) 766 error = EFAULT; 767 break; 768 769 case PIOCSFPREG: /* set floating-point registers */ 770 if (!prhasfp()) 771 error = EINVAL; /* No FP support */ 772 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 773 error = EBUSY; 774 else { 775 /* drop p_lock while touching the lwp's stack */ 776 mutex_exit(&p->p_lock); 777 prsetprfpregs(lwp, &un.fpregs); 778 mutex_enter(&p->p_lock); 779 } 780 prunlock(pnp); 781 break; 782 783 case PIOCGXREGSIZE: /* get the size of the extra registers */ 784 { 785 if (prhasx(p)) { 786 size_t xregsize; 787 int abisize; 788 789 xregsize = prgetprxregsize(p); 790 prunlock(pnp); 791 if (xregsize > INT_MAX) { 792 error = EOVERFLOW; 793 break; 794 } 795 796 abisize = (int)xregsize; 797 if (copyout(&abisize, cmaddr, sizeof (abisize))) 798 error = EFAULT; 799 } else { 800 prunlock(pnp); 801 error = EINVAL; /* No extra register support */ 802 } 803 break; 804 } 805 806 case PIOCGXREG: /* get extra registers */ 807 if (prhasx(p)) { 808 bzero(thing, thingsize); 809 if (t->t_state == TS_STOPPED || VSTOPPED(t)) { 810 /* drop p_lock to touch the stack */ 811 mutex_exit(&p->p_lock); 812 prgetprxregs(lwp, thing); 813 mutex_enter(&p->p_lock); 814 } 815 prunlock(pnp); 816 if (copyout(thing, cmaddr, thingsize)) 817 error = EFAULT; 818 } else { 819 prunlock(pnp); 820 error = EINVAL; /* No extra register support */ 821 } 822 if (thing) { 823 kmem_free(thing, thingsize); 824 thing = NULL; 825 } 826 break; 827 828 case PIOCSTATUS: /* get process/lwp status */ 829 oprgetstatus(t, &un.prstat, VTOZONE(vp)); 830 prunlock(pnp); 831 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat))) 832 error = EFAULT; 833 break; 834 835 case PIOCLSTATUS: /* get status for process & all lwps */ 836 { 837 int Nlwp; 838 int nlwp; 839 prstatus_t *Bprsp; 840 prstatus_t *prsp; 841 842 nlwp = Nlwp = p->p_lwpcnt; 843 844 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus_t)) { 845 kmem_free(thing, thingsize); 846 thing = NULL; 847 } 848 if (thing == NULL) { 849 thingsize = (Nlwp+1) * sizeof (prstatus_t); 850 thing = kmem_alloc(thingsize, KM_NOSLEEP); 851 } 852 if (thing == NULL) { 853 prunlock(pnp); 854 goto startover; 855 } 856 857 Bprsp = thing; 858 thing = NULL; 859 prsp = Bprsp; 860 oprgetstatus(t, prsp, VTOZONE(vp)); 861 t = p->p_tlist; 862 do { 863 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 864 ASSERT(nlwp > 0); 865 --nlwp; 866 oprgetstatus(t, ++prsp, VTOZONE(vp)); 867 } while ((t = t->t_forw) != p->p_tlist); 868 ASSERT(nlwp == 0); 869 prunlock(pnp); 870 if (copyout(Bprsp, cmaddr, (Nlwp+1) * sizeof (prstatus_t))) 871 error = EFAULT; 872 873 kmem_free(Bprsp, (Nlwp+1) * sizeof (prstatus_t)); 874 break; 875 } 876 877 case PIOCPSINFO: /* get ps(1) information */ 878 { 879 prpsinfo_t *psp = &un.prps; 880 881 oprgetpsinfo(p, psp, 882 (pnp->pr_type == PR_LWPIDFILE)? pcp->prc_thread : NULL); 883 884 prunlock(pnp); 885 if (copyout(&un.prps, cmaddr, sizeof (un.prps))) 886 error = EFAULT; 887 break; 888 } 889 890 case PIOCMAXSIG: /* get maximum signal number */ 891 { 892 int n = nsig-1; 893 894 prunlock(pnp); 895 if (copyout(&n, cmaddr, sizeof (n))) 896 error = EFAULT; 897 break; 898 } 899 900 case PIOCACTION: /* get signal action structures */ 901 { 902 uint_t sig; 903 struct sigaction *sap = thing; 904 905 up = PTOU(p); 906 for (sig = 1; sig < nsig; sig++) 907 prgetaction(p, up, sig, &sap[sig-1]); 908 prunlock(pnp); 909 if (copyout(sap, cmaddr, (nsig-1) * sizeof (struct sigaction))) 910 error = EFAULT; 911 kmem_free(sap, (nsig-1) * sizeof (struct sigaction)); 912 thing = NULL; 913 break; 914 } 915 916 case PIOCGHOLD: /* get signal-hold mask */ 917 prgethold(t, &un.holdmask); 918 prunlock(pnp); 919 if (copyout(&un.holdmask, cmaddr, sizeof (un.holdmask))) 920 error = EFAULT; 921 break; 922 923 case PIOCSHOLD: /* set signal-hold mask */ 924 pr_sethold(pnp, &un.holdmask); 925 prunlock(pnp); 926 break; 927 928 case PIOCNMAP: /* get number of memory mappings */ 929 { 930 uint_t n; 931 struct as *as = p->p_as; 932 933 if ((p->p_flag & SSYS) || as == &kas) 934 n = 0; 935 else { 936 mutex_exit(&p->p_lock); 937 AS_LOCK_ENTER(as, RW_WRITER); 938 n = prnsegs(as, 0); 939 AS_LOCK_EXIT(as); 940 mutex_enter(&p->p_lock); 941 } 942 prunlock(pnp); 943 if (copyout(&n, cmaddr, sizeof (uint_t))) 944 error = EFAULT; 945 break; 946 } 947 948 case PIOCMAP: /* get memory map information */ 949 { 950 list_t iolhead; 951 struct as *as = p->p_as; 952 953 if ((p->p_flag & SSYS) || as == &kas) { 954 error = 0; 955 prunlock(pnp); 956 } else { 957 mutex_exit(&p->p_lock); 958 AS_LOCK_ENTER(as, RW_WRITER); 959 error = oprgetmap(p, &iolhead); 960 AS_LOCK_EXIT(as); 961 mutex_enter(&p->p_lock); 962 prunlock(pnp); 963 964 error = pr_iol_copyout_and_free(&iolhead, 965 &cmaddr, error); 966 } 967 /* 968 * The procfs PIOCMAP ioctl returns an all-zero buffer 969 * to indicate the end of the prmap[] array. 970 * Append it to whatever has already been copied out. 971 */ 972 bzero(&un.prmap, sizeof (un.prmap)); 973 if (!error && copyout(&un.prmap, cmaddr, sizeof (un.prmap))) 974 error = EFAULT; 975 976 break; 977 } 978 979 case PIOCGFAULT: /* get mask of traced faults */ 980 prassignset(&un.fltmask, &p->p_fltmask); 981 prunlock(pnp); 982 if (copyout(&un.fltmask, cmaddr, sizeof (un.fltmask))) 983 error = EFAULT; 984 break; 985 986 case PIOCSFAULT: /* set mask of traced faults */ 987 pr_setfault(p, &un.fltmask); 988 prunlock(pnp); 989 break; 990 991 case PIOCCFAULT: /* clear current fault */ 992 lwp->lwp_curflt = 0; 993 prunlock(pnp); 994 break; 995 996 case PIOCCRED: /* get process credentials */ 997 { 998 cred_t *cp; 999 1000 mutex_enter(&p->p_crlock); 1001 cp = p->p_cred; 1002 un.prcred.pr_euid = crgetuid(cp); 1003 un.prcred.pr_ruid = crgetruid(cp); 1004 un.prcred.pr_suid = crgetsuid(cp); 1005 un.prcred.pr_egid = crgetgid(cp); 1006 un.prcred.pr_rgid = crgetrgid(cp); 1007 un.prcred.pr_sgid = crgetsgid(cp); 1008 un.prcred.pr_ngroups = crgetngroups(cp); 1009 mutex_exit(&p->p_crlock); 1010 1011 prunlock(pnp); 1012 if (copyout(&un.prcred, cmaddr, sizeof (un.prcred))) 1013 error = EFAULT; 1014 break; 1015 } 1016 1017 case PIOCGROUPS: /* get supplementary groups */ 1018 { 1019 cred_t *cp; 1020 1021 mutex_enter(&p->p_crlock); 1022 cp = p->p_cred; 1023 crhold(cp); 1024 mutex_exit(&p->p_crlock); 1025 1026 prunlock(pnp); 1027 if (copyout(crgetgroups(cp), cmaddr, 1028 MAX(crgetngroups(cp), 1) * sizeof (gid_t))) 1029 error = EFAULT; 1030 crfree(cp); 1031 break; 1032 } 1033 1034 case PIOCUSAGE: /* get usage info */ 1035 { 1036 /* 1037 * For an lwp file descriptor, return just the lwp usage. 1038 * For a process file descriptor, return total usage, 1039 * all current lwps plus all defunct lwps. 1040 */ 1041 prhusage_t *pup = &un.prhusage; 1042 prusage_t *upup; 1043 1044 bzero(pup, sizeof (*pup)); 1045 pup->pr_tstamp = gethrtime(); 1046 1047 if (pnp->pr_type == PR_LWPIDFILE) { 1048 t = pcp->prc_thread; 1049 if (t != NULL) 1050 prgetusage(t, pup); 1051 else 1052 error = ENOENT; 1053 } else { 1054 pup->pr_count = p->p_defunct; 1055 pup->pr_create = p->p_mstart; 1056 pup->pr_term = p->p_mterm; 1057 1058 pup->pr_rtime = p->p_mlreal; 1059 pup->pr_utime = p->p_acct[LMS_USER]; 1060 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 1061 pup->pr_ttime = p->p_acct[LMS_TRAP]; 1062 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 1063 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 1064 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 1065 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 1066 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 1067 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 1068 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 1069 1070 pup->pr_minf = p->p_ru.minflt; 1071 pup->pr_majf = p->p_ru.majflt; 1072 pup->pr_nswap = p->p_ru.nswap; 1073 pup->pr_inblk = p->p_ru.inblock; 1074 pup->pr_oublk = p->p_ru.oublock; 1075 pup->pr_msnd = p->p_ru.msgsnd; 1076 pup->pr_mrcv = p->p_ru.msgrcv; 1077 pup->pr_sigs = p->p_ru.nsignals; 1078 pup->pr_vctx = p->p_ru.nvcsw; 1079 pup->pr_ictx = p->p_ru.nivcsw; 1080 pup->pr_sysc = p->p_ru.sysc; 1081 pup->pr_ioch = p->p_ru.ioch; 1082 1083 /* 1084 * Add the usage information for each active lwp. 1085 */ 1086 if ((t = p->p_tlist) != NULL && 1087 !(pcp->prc_flags & PRC_DESTROY)) { 1088 do { 1089 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 1090 pup->pr_count++; 1091 praddusage(t, pup); 1092 } while ((t = t->t_forw) != p->p_tlist); 1093 } 1094 } 1095 1096 prunlock(pnp); 1097 1098 upup = kmem_zalloc(sizeof (*upup), KM_SLEEP); 1099 prcvtusage(&un.prhusage, upup); 1100 if (copyout(upup, cmaddr, sizeof (*upup))) 1101 error = EFAULT; 1102 kmem_free(upup, sizeof (*upup)); 1103 1104 break; 1105 } 1106 1107 case PIOCLUSAGE: /* get detailed usage info */ 1108 { 1109 int Nlwp; 1110 int nlwp; 1111 prusage_t *upup; 1112 prusage_t *Bupup; 1113 prhusage_t *pup; 1114 hrtime_t curtime; 1115 1116 nlwp = Nlwp = (pcp->prc_flags & PRC_DESTROY)? 0 : p->p_lwpcnt; 1117 1118 if (thing && thingsize != 1119 sizeof (prhusage_t) + (Nlwp+1) * sizeof (prusage_t)) { 1120 kmem_free(thing, thingsize); 1121 thing = NULL; 1122 } 1123 if (thing == NULL) { 1124 thingsize = sizeof (prhusage_t) + 1125 (Nlwp+1) * sizeof (prusage_t); 1126 thing = kmem_alloc(thingsize, KM_NOSLEEP); 1127 } 1128 if (thing == NULL) { 1129 prunlock(pnp); 1130 goto startover; 1131 } 1132 1133 pup = thing; 1134 upup = Bupup = (prusage_t *)(pup + 1); 1135 1136 ASSERT(p == pcp->prc_proc); 1137 1138 curtime = gethrtime(); 1139 1140 /* 1141 * First the summation over defunct lwps. 1142 */ 1143 bzero(pup, sizeof (*pup)); 1144 pup->pr_count = p->p_defunct; 1145 pup->pr_tstamp = curtime; 1146 pup->pr_create = p->p_mstart; 1147 pup->pr_term = p->p_mterm; 1148 1149 pup->pr_rtime = p->p_mlreal; 1150 pup->pr_utime = p->p_acct[LMS_USER]; 1151 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 1152 pup->pr_ttime = p->p_acct[LMS_TRAP]; 1153 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 1154 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 1155 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 1156 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 1157 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 1158 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 1159 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 1160 1161 pup->pr_minf = p->p_ru.minflt; 1162 pup->pr_majf = p->p_ru.majflt; 1163 pup->pr_nswap = p->p_ru.nswap; 1164 pup->pr_inblk = p->p_ru.inblock; 1165 pup->pr_oublk = p->p_ru.oublock; 1166 pup->pr_msnd = p->p_ru.msgsnd; 1167 pup->pr_mrcv = p->p_ru.msgrcv; 1168 pup->pr_sigs = p->p_ru.nsignals; 1169 pup->pr_vctx = p->p_ru.nvcsw; 1170 pup->pr_ictx = p->p_ru.nivcsw; 1171 pup->pr_sysc = p->p_ru.sysc; 1172 pup->pr_ioch = p->p_ru.ioch; 1173 1174 prcvtusage(pup, upup); 1175 1176 /* 1177 * Fill one prusage struct for each active lwp. 1178 */ 1179 if ((t = p->p_tlist) != NULL && 1180 !(pcp->prc_flags & PRC_DESTROY)) { 1181 do { 1182 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 1183 ASSERT(nlwp > 0); 1184 --nlwp; 1185 upup++; 1186 prgetusage(t, pup); 1187 prcvtusage(pup, upup); 1188 } while ((t = t->t_forw) != p->p_tlist); 1189 } 1190 ASSERT(nlwp == 0); 1191 1192 prunlock(pnp); 1193 if (copyout(Bupup, cmaddr, (Nlwp+1) * sizeof (prusage_t))) 1194 error = EFAULT; 1195 kmem_free(thing, thingsize); 1196 thing = NULL; 1197 break; 1198 } 1199 1200 case PIOCNAUXV: /* get number of aux vector entries */ 1201 { 1202 int n = __KERN_NAUXV_IMPL; 1203 1204 prunlock(pnp); 1205 if (copyout(&n, cmaddr, sizeof (int))) 1206 error = EFAULT; 1207 break; 1208 } 1209 1210 case PIOCAUXV: /* get aux vector (see sys/auxv.h) */ 1211 { 1212 up = PTOU(p); 1213 bcopy(up->u_auxv, un.auxv, 1214 __KERN_NAUXV_IMPL * sizeof (auxv_t)); 1215 prunlock(pnp); 1216 if (copyout(un.auxv, cmaddr, 1217 __KERN_NAUXV_IMPL * sizeof (auxv_t))) 1218 error = EFAULT; 1219 break; 1220 } 1221 1222 #if defined(__x86) 1223 case PIOCNLDT: /* get number of LDT entries */ 1224 { 1225 int n; 1226 1227 mutex_exit(&p->p_lock); 1228 mutex_enter(&p->p_ldtlock); 1229 n = prnldt(p); 1230 mutex_exit(&p->p_ldtlock); 1231 mutex_enter(&p->p_lock); 1232 prunlock(pnp); 1233 if (copyout(&n, cmaddr, sizeof (n))) 1234 error = EFAULT; 1235 break; 1236 } 1237 1238 case PIOCLDT: /* get LDT entries */ 1239 { 1240 struct ssd *ssd; 1241 int n; 1242 1243 mutex_exit(&p->p_lock); 1244 mutex_enter(&p->p_ldtlock); 1245 n = prnldt(p); 1246 1247 if (thing && thingsize != (n+1) * sizeof (*ssd)) { 1248 kmem_free(thing, thingsize); 1249 thing = NULL; 1250 } 1251 if (thing == NULL) { 1252 thingsize = (n+1) * sizeof (*ssd); 1253 thing = kmem_alloc(thingsize, KM_NOSLEEP); 1254 } 1255 if (thing == NULL) { 1256 mutex_exit(&p->p_ldtlock); 1257 mutex_enter(&p->p_lock); 1258 prunlock(pnp); 1259 goto startover; 1260 } 1261 1262 ssd = thing; 1263 thing = NULL; 1264 if (n != 0) 1265 prgetldt(p, ssd); 1266 mutex_exit(&p->p_ldtlock); 1267 mutex_enter(&p->p_lock); 1268 prunlock(pnp); 1269 1270 /* mark the end of the list with a null entry */ 1271 bzero(&ssd[n], sizeof (*ssd)); 1272 if (copyout(ssd, cmaddr, (n+1) * sizeof (*ssd))) 1273 error = EFAULT; 1274 kmem_free(ssd, (n+1) * sizeof (*ssd)); 1275 break; 1276 } 1277 #endif /* __x86 */ 1278 1279 #if defined(__sparc) 1280 case PIOCGWIN: /* get gwindows_t (see sys/reg.h) */ 1281 { 1282 gwindows_t *gwp = thing; 1283 1284 /* drop p->p_lock while touching the stack */ 1285 mutex_exit(&p->p_lock); 1286 bzero(gwp, sizeof (*gwp)); 1287 prgetwindows(lwp, gwp); 1288 mutex_enter(&p->p_lock); 1289 prunlock(pnp); 1290 if (copyout(gwp, cmaddr, sizeof (*gwp))) 1291 error = EFAULT; 1292 kmem_free(gwp, sizeof (gwindows_t)); 1293 thing = NULL; 1294 break; 1295 } 1296 #endif /* __sparc */ 1297 1298 default: 1299 prunlock(pnp); 1300 error = EINVAL; 1301 break; 1302 1303 } 1304 1305 ASSERT(thing == NULL); 1306 ASSERT(xpnp == NULL); 1307 return (error); 1308 } 1309 1310 #ifdef _SYSCALL32_IMPL 1311 1312 static int oprgetmap32(proc_t *, list_t *); 1313 1314 void 1315 oprgetstatus32(kthread_t *t, prstatus32_t *sp, zone_t *zp) 1316 { 1317 proc_t *p = ttoproc(t); 1318 klwp_t *lwp = ttolwp(t); 1319 int32_t flags; 1320 user_t *up; 1321 ulong_t instr; 1322 1323 ASSERT(MUTEX_HELD(&p->p_lock)); 1324 1325 up = PTOU(p); 1326 bzero(sp, sizeof (*sp)); 1327 flags = 0L; 1328 if (t->t_state == TS_STOPPED) { 1329 flags |= PR_STOPPED; 1330 if ((t->t_schedflag & TS_PSTART) == 0) 1331 flags |= PR_ISTOP; 1332 } else if (VSTOPPED(t)) { 1333 flags |= PR_STOPPED|PR_ISTOP; 1334 } 1335 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP)) 1336 flags |= PR_DSTOP; 1337 if (lwp->lwp_asleep) 1338 flags |= PR_ASLEEP; 1339 if (p->p_proc_flag & P_PR_FORK) 1340 flags |= PR_FORK; 1341 if (p->p_proc_flag & P_PR_RUNLCL) 1342 flags |= PR_RLC; 1343 if (p->p_proc_flag & P_PR_KILLCL) 1344 flags |= PR_KLC; 1345 if (p->p_proc_flag & P_PR_ASYNC) 1346 flags |= PR_ASYNC; 1347 if (p->p_proc_flag & P_PR_BPTADJ) 1348 flags |= PR_BPTADJ; 1349 if (p->p_proc_flag & P_PR_PTRACE) 1350 flags |= PR_PCOMPAT; 1351 if (t->t_proc_flag & TP_MSACCT) 1352 flags |= PR_MSACCT; 1353 sp->pr_flags = flags; 1354 if (VSTOPPED(t)) { 1355 sp->pr_why = PR_REQUESTED; 1356 sp->pr_what = 0; 1357 } else { 1358 sp->pr_why = t->t_whystop; 1359 sp->pr_what = t->t_whatstop; 1360 } 1361 1362 if (t->t_whystop == PR_FAULTED) { 1363 siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info); 1364 if (t->t_whatstop == FLTPAGE) 1365 sp->pr_info.si_addr = 1366 (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr; 1367 } else if (lwp->lwp_curinfo) 1368 siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info); 1369 1370 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID && 1371 sp->pr_info.si_zoneid != zp->zone_id) { 1372 sp->pr_info.si_pid = zp->zone_zsched->p_pid; 1373 sp->pr_info.si_uid = 0; 1374 sp->pr_info.si_ctid = -1; 1375 sp->pr_info.si_zoneid = zp->zone_id; 1376 } 1377 1378 sp->pr_cursig = lwp->lwp_cursig; 1379 prassignset(&sp->pr_sigpend, &p->p_sig); 1380 prassignset(&sp->pr_lwppend, &t->t_sig); 1381 prgethold(t, &sp->pr_sighold); 1382 sp->pr_altstack.ss_sp = 1383 (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp; 1384 sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size; 1385 sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags; 1386 prgetaction32(p, up, lwp->lwp_cursig, &sp->pr_action); 1387 sp->pr_pid = p->p_pid; 1388 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 1389 (p->p_flag & SZONETOP)) { 1390 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 1391 /* 1392 * Inside local zones, fake zsched's pid as parent pids for 1393 * processes which reference processes outside of the zone. 1394 */ 1395 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 1396 } else { 1397 sp->pr_ppid = p->p_ppid; 1398 } 1399 sp->pr_pgrp = p->p_pgrp; 1400 sp->pr_sid = p->p_sessp->s_sid; 1401 hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime); 1402 hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime); 1403 TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime); 1404 TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime); 1405 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name, 1406 sizeof (sp->pr_clname) - 1); 1407 sp->pr_who = t->t_tid; 1408 sp->pr_nlwp = p->p_lwpcnt; 1409 sp->pr_brkbase = (caddr32_t)(uintptr_t)p->p_brkbase; 1410 sp->pr_brksize = (size32_t)p->p_brksize; 1411 sp->pr_stkbase = (caddr32_t)(uintptr_t)prgetstackbase(p); 1412 sp->pr_stksize = (size32_t)p->p_stksize; 1413 sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext; 1414 sp->pr_processor = t->t_cpu->cpu_id; 1415 sp->pr_bind = t->t_bind_cpu; 1416 1417 /* 1418 * Fetch the current instruction, if not a system process. 1419 * We don't attempt this unless the lwp is stopped. 1420 */ 1421 if ((p->p_flag & SSYS) || p->p_as == &kas) 1422 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL); 1423 else if (!(flags & PR_STOPPED)) 1424 sp->pr_flags |= PR_PCINVAL; 1425 else if (!prfetchinstr(lwp, &instr)) 1426 sp->pr_flags |= PR_PCINVAL; 1427 else 1428 sp->pr_instr = (uint32_t)instr; 1429 1430 /* 1431 * Drop p_lock while touching the lwp's stack. 1432 */ 1433 mutex_exit(&p->p_lock); 1434 if (prisstep(lwp)) 1435 sp->pr_flags |= PR_STEP; 1436 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) { 1437 int i; 1438 auxv_t *auxp; 1439 1440 sp->pr_syscall = get_syscall32_args(lwp, 1441 (int *)sp->pr_sysarg, &i); 1442 sp->pr_nsysarg = (short)i; 1443 if (t->t_whystop == PR_SYSEXIT && t->t_sysnum == SYS_execve) { 1444 sp->pr_sysarg[0] = 0; 1445 sp->pr_sysarg[1] = (caddr32_t)up->u_argv; 1446 sp->pr_sysarg[2] = (caddr32_t)up->u_envp; 1447 for (i = 0, auxp = up->u_auxv; 1448 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]); 1449 i++, auxp++) { 1450 if (auxp->a_type == AT_SUN_EXECNAME) { 1451 sp->pr_sysarg[0] = 1452 (caddr32_t) 1453 (uintptr_t)auxp->a_un.a_ptr; 1454 break; 1455 } 1456 } 1457 } 1458 } 1459 if ((flags & PR_STOPPED) || t == curthread) 1460 prgetprregs32(lwp, sp->pr_reg); 1461 mutex_enter(&p->p_lock); 1462 } 1463 1464 void 1465 oprgetpsinfo32(proc_t *p, prpsinfo32_t *psp, kthread_t *tp) 1466 { 1467 kthread_t *t; 1468 char c, state; 1469 user_t *up; 1470 dev_t d; 1471 uint64_t pct; 1472 int retval, niceval; 1473 cred_t *cred; 1474 struct as *as; 1475 hrtime_t hrutime, hrstime, cur_time; 1476 1477 ASSERT(MUTEX_HELD(&p->p_lock)); 1478 1479 bzero(psp, sizeof (*psp)); 1480 1481 if ((t = tp) == NULL) 1482 t = prchoose(p); /* returns locked thread */ 1483 else 1484 thread_lock(t); 1485 1486 /* kludge: map thread state enum into process state enum */ 1487 1488 if (t == NULL) { 1489 state = TS_ZOMB; 1490 } else { 1491 state = VSTOPPED(t) ? TS_STOPPED : t->t_state; 1492 thread_unlock(t); 1493 } 1494 1495 switch (state) { 1496 case TS_SLEEP: state = SSLEEP; break; 1497 case TS_RUN: state = SRUN; break; 1498 case TS_ONPROC: state = SONPROC; break; 1499 case TS_ZOMB: state = SZOMB; break; 1500 case TS_STOPPED: state = SSTOP; break; 1501 default: state = 0; break; 1502 } 1503 switch (state) { 1504 case SSLEEP: c = 'S'; break; 1505 case SRUN: c = 'R'; break; 1506 case SZOMB: c = 'Z'; break; 1507 case SSTOP: c = 'T'; break; 1508 case SIDL: c = 'I'; break; 1509 case SONPROC: c = 'O'; break; 1510 #ifdef SXBRK 1511 case SXBRK: c = 'X'; break; 1512 #endif 1513 default: c = '?'; break; 1514 } 1515 psp->pr_state = state; 1516 psp->pr_sname = c; 1517 psp->pr_zomb = (state == SZOMB); 1518 /* 1519 * only export SSYS and SMSACCT; everything else is off-limits to 1520 * userland apps. 1521 */ 1522 psp->pr_flag = p->p_flag & (SSYS | SMSACCT); 1523 1524 mutex_enter(&p->p_crlock); 1525 cred = p->p_cred; 1526 psp->pr_uid = crgetruid(cred); 1527 psp->pr_gid = crgetrgid(cred); 1528 psp->pr_euid = crgetuid(cred); 1529 psp->pr_egid = crgetgid(cred); 1530 mutex_exit(&p->p_crlock); 1531 1532 psp->pr_pid = p->p_pid; 1533 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 1534 (p->p_flag & SZONETOP)) { 1535 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 1536 /* 1537 * Inside local zones, fake zsched's pid as parent pids for 1538 * processes which reference processes outside of the zone. 1539 */ 1540 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 1541 } else { 1542 psp->pr_ppid = p->p_ppid; 1543 } 1544 psp->pr_pgrp = p->p_pgrp; 1545 psp->pr_sid = p->p_sessp->s_sid; 1546 psp->pr_addr = 0; /* cannot represent 64-bit addr in 32 bits */ 1547 hrutime = mstate_aggr_state(p, LMS_USER); 1548 hrstime = mstate_aggr_state(p, LMS_SYSTEM); 1549 hrt2ts32(hrutime + hrstime, &psp->pr_time); 1550 TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime); 1551 switch (p->p_model) { 1552 case DATAMODEL_ILP32: 1553 psp->pr_dmodel = PR_MODEL_ILP32; 1554 break; 1555 case DATAMODEL_LP64: 1556 psp->pr_dmodel = PR_MODEL_LP64; 1557 break; 1558 } 1559 if (state == SZOMB || t == NULL) { 1560 int wcode = p->p_wcode; /* must be atomic read */ 1561 1562 if (wcode) 1563 psp->pr_wstat = wstat(wcode, p->p_wdata); 1564 psp->pr_lttydev = PRNODEV32; 1565 psp->pr_ottydev = (o_dev_t)PRNODEV32; 1566 psp->pr_size = 0; 1567 psp->pr_rssize = 0; 1568 psp->pr_pctmem = 0; 1569 } else { 1570 up = PTOU(p); 1571 psp->pr_wchan = 0; /* cannot represent in 32 bits */ 1572 psp->pr_pri = t->t_pri; 1573 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name, 1574 sizeof (psp->pr_clname) - 1); 1575 retval = CL_DONICE(t, NULL, 0, &niceval); 1576 if (retval == 0) { 1577 psp->pr_oldpri = v.v_maxsyspri - psp->pr_pri; 1578 psp->pr_nice = niceval + NZERO; 1579 } else { 1580 psp->pr_oldpri = 0; 1581 psp->pr_nice = 0; 1582 } 1583 d = cttydev(p); 1584 #ifdef sun 1585 { 1586 extern dev_t rwsconsdev, rconsdev, uconsdev; 1587 /* 1588 * If the controlling terminal is the real 1589 * or workstation console device, map to what the 1590 * user thinks is the console device. Handle case when 1591 * rwsconsdev or rconsdev is set to NODEV for Starfire. 1592 */ 1593 if ((d == rwsconsdev || d == rconsdev) && d != NODEV) 1594 d = uconsdev; 1595 } 1596 #endif 1597 (void) cmpldev(&psp->pr_lttydev, d); 1598 psp->pr_ottydev = cmpdev(d); 1599 TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start); 1600 bcopy(up->u_comm, psp->pr_fname, 1601 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1)); 1602 bcopy(up->u_psargs, psp->pr_psargs, 1603 MIN(PRARGSZ-1, PSARGSZ)); 1604 psp->pr_syscall = t->t_sysnum; 1605 psp->pr_argc = up->u_argc; 1606 psp->pr_argv = (caddr32_t)up->u_argv; 1607 psp->pr_envp = (caddr32_t)up->u_envp; 1608 1609 /* compute %cpu for the lwp or process */ 1610 pct = 0; 1611 if ((t = tp) == NULL) 1612 t = p->p_tlist; 1613 cur_time = gethrtime_unscaled(); 1614 do { 1615 pct += cpu_update_pct(t, cur_time); 1616 if (tp != NULL) /* just do the one lwp */ 1617 break; 1618 } while ((t = t->t_forw) != p->p_tlist); 1619 1620 psp->pr_pctcpu = prgetpctcpu(pct); 1621 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */ 1622 if (psp->pr_cpu > 99) 1623 psp->pr_cpu = 99; 1624 1625 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 1626 psp->pr_size = 0; 1627 psp->pr_rssize = 0; 1628 psp->pr_pctmem = 0; 1629 } else { 1630 mutex_exit(&p->p_lock); 1631 AS_LOCK_ENTER(as, RW_READER); 1632 psp->pr_size = (size32_t)btopr(as->a_resvsize); 1633 psp->pr_rssize = (size32_t)rm_asrss(as); 1634 psp->pr_pctmem = rm_pctmemory(as); 1635 AS_LOCK_EXIT(as); 1636 mutex_enter(&p->p_lock); 1637 } 1638 } 1639 psp->pr_bysize = (size32_t)ptob(psp->pr_size); 1640 psp->pr_byrssize = (size32_t)ptob(psp->pr_rssize); 1641 1642 /* 1643 * If we are looking at an LP64 process, zero out 1644 * the fields that cannot be represented in ILP32. 1645 */ 1646 if (p->p_model != DATAMODEL_ILP32) { 1647 psp->pr_size = 0; 1648 psp->pr_rssize = 0; 1649 psp->pr_bysize = 0; 1650 psp->pr_byrssize = 0; 1651 psp->pr_argv = 0; 1652 psp->pr_envp = 0; 1653 } 1654 } 1655 1656 /*ARGSUSED*/ 1657 static int 1658 prioctl32(struct vnode *vp, int cmd, intptr_t arg, int flag, cred_t *cr, 1659 int *rvalp, caller_context_t *ct) 1660 { 1661 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 1662 caddr_t cmaddr = (caddr_t)arg; 1663 proc_t *p; 1664 user_t *up; 1665 kthread_t *t; 1666 klwp_t *lwp; 1667 prnode_t *pnp = VTOP(vp); 1668 prcommon_t *pcp; 1669 prnode_t *xpnp = NULL; 1670 int error; 1671 int zdisp; 1672 void *thing = NULL; 1673 size_t thingsize = 0; 1674 1675 /* 1676 * For copyin()/copyout(). 1677 */ 1678 union { 1679 caddr32_t va; 1680 int signo; 1681 int nice; 1682 uint_t lwpid; 1683 int32_t flags; 1684 prstatus32_t prstat; 1685 prrun32_t prrun; 1686 sigset_t smask; 1687 siginfo32_t info; 1688 sysset_t prmask; 1689 prgregset32_t regs; 1690 prfpregset32_t fpregs; 1691 prpsinfo32_t prps; 1692 sigset_t holdmask; 1693 fltset_t fltmask; 1694 prcred_t prcred; 1695 prusage32_t prusage; 1696 prhusage_t prhusage; 1697 ioc_prmap32_t prmap; 1698 auxv32_t auxv[__KERN_NAUXV_IMPL]; 1699 } un32; 1700 1701 /* 1702 * Native objects for internal use. 1703 */ 1704 union { 1705 caddr_t va; 1706 int signo; 1707 int nice; 1708 uint_t lwpid; 1709 long flags; 1710 prstatus_t prstat; 1711 prrun_t prrun; 1712 sigset_t smask; 1713 siginfo_t info; 1714 sysset_t prmask; 1715 prgregset_t regs; 1716 prpsinfo_t prps; 1717 sigset_t holdmask; 1718 fltset_t fltmask; 1719 prcred_t prcred; 1720 prusage_t prusage; 1721 prhusage_t prhusage; 1722 auxv_t auxv[__KERN_NAUXV_IMPL]; 1723 } un; 1724 1725 if (pnp->pr_type == PR_TMPL) 1726 return (prctioctl(pnp, cmd, arg, flag, cr)); 1727 1728 /* 1729 * Support for old /proc interface. 1730 */ 1731 if (pnp->pr_pidfile != NULL) { 1732 ASSERT(pnp->pr_type == PR_PIDDIR); 1733 vp = pnp->pr_pidfile; 1734 pnp = VTOP(vp); 1735 ASSERT(pnp->pr_type == PR_PIDFILE); 1736 } 1737 1738 if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE) 1739 return (ENOTTY); 1740 1741 /* 1742 * Fail ioctls which are logically "write" requests unless 1743 * the user has write permission. 1744 */ 1745 if ((flag & FWRITE) == 0 && isprwrioctl(cmd)) 1746 return (EBADF); 1747 1748 /* 1749 * The following command is no longer supported. It was present on SPARC 1750 * and would always error on other platforms. We now explicitly return 1751 * ENOTSUP to make this more explicit. 1752 */ 1753 if (cmd == PIOCSXREG) 1754 return (ENOTSUP); 1755 1756 /* 1757 * Perform any necessary copyin() operations before 1758 * locking the process. Helps avoid deadlocks and 1759 * improves performance. 1760 * 1761 * Also, detect invalid ioctl codes here to avoid 1762 * locking a process unnecessarily. 1763 * 1764 * Also, prepare to allocate space that will be needed below, 1765 * case by case. 1766 */ 1767 error = 0; 1768 switch (cmd) { 1769 case PIOCGETPR: 1770 thingsize = sizeof (proc_t); 1771 break; 1772 case PIOCGETU: 1773 thingsize = sizeof (user_t); 1774 break; 1775 case PIOCSTOP: 1776 case PIOCWSTOP: 1777 case PIOCLWPIDS: 1778 case PIOCGTRACE: 1779 case PIOCGENTRY: 1780 case PIOCGEXIT: 1781 case PIOCSRLC: 1782 case PIOCRRLC: 1783 case PIOCSFORK: 1784 case PIOCRFORK: 1785 case PIOCGREG: 1786 case PIOCGFPREG: 1787 case PIOCSTATUS: 1788 case PIOCLSTATUS: 1789 case PIOCPSINFO: 1790 case PIOCMAXSIG: 1791 case PIOCGXREGSIZE: 1792 break; 1793 case PIOCGXREG: /* get extra registers */ 1794 thingsize = prgetprxregsize(p); 1795 break; 1796 case PIOCACTION: 1797 thingsize = (nsig-1) * sizeof (struct sigaction32); 1798 break; 1799 case PIOCGHOLD: 1800 case PIOCNMAP: 1801 case PIOCMAP: 1802 case PIOCGFAULT: 1803 case PIOCCFAULT: 1804 case PIOCCRED: 1805 case PIOCGROUPS: 1806 case PIOCUSAGE: 1807 case PIOCLUSAGE: 1808 break; 1809 case PIOCOPENPD: 1810 /* 1811 * We will need this below. 1812 * Allocate it now, before locking the process. 1813 */ 1814 xpnp = prgetnode(vp, PR_OPAGEDATA); 1815 break; 1816 case PIOCNAUXV: 1817 case PIOCAUXV: 1818 break; 1819 1820 #if defined(__i386_COMPAT) 1821 case PIOCNLDT: 1822 case PIOCLDT: 1823 break; 1824 #endif /* __i386_COMPAT */ 1825 1826 #if defined(__sparc) 1827 case PIOCGWIN: 1828 thingsize = sizeof (gwindows32_t); 1829 break; 1830 #endif /* __sparc */ 1831 1832 case PIOCOPENM: /* open mapped object for reading */ 1833 if (cmaddr == NULL) 1834 un32.va = (caddr32_t)(uintptr_t)NULL; 1835 else if (copyin(cmaddr, &un32.va, sizeof (un32.va))) 1836 error = EFAULT; 1837 break; 1838 1839 case PIOCRUN: /* make lwp or process runnable */ 1840 if (cmaddr == NULL) 1841 un32.prrun.pr_flags = 0; 1842 else if (copyin(cmaddr, &un32.prrun, sizeof (un32.prrun))) 1843 error = EFAULT; 1844 break; 1845 1846 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 1847 if (copyin(cmaddr, &un32.lwpid, sizeof (un32.lwpid))) 1848 error = EFAULT; 1849 break; 1850 1851 case PIOCSTRACE: /* set signal trace mask */ 1852 if (copyin(cmaddr, &un32.smask, sizeof (un32.smask))) 1853 error = EFAULT; 1854 break; 1855 1856 case PIOCSSIG: /* set current signal */ 1857 if (cmaddr == NULL) 1858 un32.info.si_signo = 0; 1859 else if (copyin(cmaddr, &un32.info, sizeof (un32.info))) 1860 error = EFAULT; 1861 break; 1862 1863 case PIOCKILL: /* send signal */ 1864 case PIOCUNKILL: /* delete a signal */ 1865 if (copyin(cmaddr, &un32.signo, sizeof (un32.signo))) 1866 error = EFAULT; 1867 break; 1868 1869 case PIOCNICE: /* set nice priority */ 1870 if (copyin(cmaddr, &un32.nice, sizeof (un32.nice))) 1871 error = EFAULT; 1872 break; 1873 1874 case PIOCSENTRY: /* set syscall entry bit mask */ 1875 case PIOCSEXIT: /* set syscall exit bit mask */ 1876 if (copyin(cmaddr, &un32.prmask, sizeof (un32.prmask))) 1877 error = EFAULT; 1878 break; 1879 1880 case PIOCSET: /* set process flags */ 1881 case PIOCRESET: /* reset process flags */ 1882 if (copyin(cmaddr, &un32.flags, sizeof (un32.flags))) 1883 error = EFAULT; 1884 break; 1885 1886 case PIOCSREG: /* set general registers */ 1887 if (copyin(cmaddr, un32.regs, sizeof (un32.regs))) 1888 error = EFAULT; 1889 break; 1890 1891 case PIOCSFPREG: /* set floating-point registers */ 1892 if (copyin(cmaddr, &un32.fpregs, sizeof (un32.fpregs))) 1893 error = EFAULT; 1894 break; 1895 1896 case PIOCSHOLD: /* set signal-hold mask */ 1897 if (copyin(cmaddr, &un32.holdmask, sizeof (un32.holdmask))) 1898 error = EFAULT; 1899 break; 1900 1901 case PIOCSFAULT: /* set mask of traced faults */ 1902 if (copyin(cmaddr, &un32.fltmask, sizeof (un32.fltmask))) 1903 error = EFAULT; 1904 break; 1905 1906 default: 1907 error = EINVAL; 1908 break; 1909 } 1910 1911 if (error) 1912 return (error); 1913 1914 startover: 1915 /* 1916 * If we need kmem_alloc()d space then we allocate it now, before 1917 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while 1918 * holding the process lock leads to deadlock with the clock thread. 1919 * (The clock thread wakes up the pageout daemon to free up space. 1920 * If the clock thread blocks behind us and we are sleeping waiting 1921 * for space, then space may never become available.) 1922 */ 1923 if (thingsize) { 1924 ASSERT(thing == NULL); 1925 thing = kmem_alloc(thingsize, KM_SLEEP); 1926 } 1927 1928 switch (cmd) { 1929 case PIOCPSINFO: 1930 case PIOCGETPR: 1931 case PIOCUSAGE: 1932 case PIOCLUSAGE: 1933 zdisp = ZYES; 1934 break; 1935 default: 1936 zdisp = ZNO; 1937 break; 1938 } 1939 1940 if ((error = prlock(pnp, zdisp)) != 0) { 1941 if (thing != NULL) 1942 kmem_free(thing, thingsize); 1943 if (xpnp) 1944 prfreenode(xpnp); 1945 return (error); 1946 } 1947 1948 pcp = pnp->pr_common; 1949 p = pcp->prc_proc; 1950 ASSERT(p != NULL); 1951 1952 /* 1953 * Choose a thread/lwp for the operation. 1954 */ 1955 if (zdisp == ZNO && cmd != PIOCSTOP && cmd != PIOCWSTOP) { 1956 if (pnp->pr_type == PR_LWPIDFILE && cmd != PIOCLSTATUS) { 1957 t = pcp->prc_thread; 1958 ASSERT(t != NULL); 1959 } else { 1960 t = prchoose(p); /* returns locked thread */ 1961 ASSERT(t != NULL); 1962 thread_unlock(t); 1963 } 1964 lwp = ttolwp(t); 1965 } 1966 1967 error = 0; 1968 switch (cmd) { 1969 1970 case PIOCGETPR: /* read struct proc */ 1971 { 1972 proc_t *prp = thing; 1973 1974 *prp = *p; 1975 prunlock(pnp); 1976 if (copyout(prp, cmaddr, sizeof (proc_t))) 1977 error = EFAULT; 1978 kmem_free(prp, sizeof (proc_t)); 1979 thing = NULL; 1980 break; 1981 } 1982 1983 case PIOCGETU: /* read u-area */ 1984 { 1985 user_t *userp = thing; 1986 1987 up = PTOU(p); 1988 *userp = *up; 1989 prunlock(pnp); 1990 if (copyout(userp, cmaddr, sizeof (user_t))) 1991 error = EFAULT; 1992 kmem_free(userp, sizeof (user_t)); 1993 thing = NULL; 1994 break; 1995 } 1996 1997 case PIOCOPENM: /* open mapped object for reading */ 1998 if (PROCESS_NOT_32BIT(p) && cmaddr != NULL) { 1999 prunlock(pnp); 2000 error = EOVERFLOW; 2001 break; 2002 } 2003 error = propenm(pnp, cmaddr, 2004 (caddr_t)(uintptr_t)un32.va, rvalp, cr); 2005 /* propenm() called prunlock(pnp) */ 2006 break; 2007 2008 case PIOCSTOP: /* stop process or lwp from running */ 2009 case PIOCWSTOP: /* wait for process or lwp to stop */ 2010 /* 2011 * Can't apply to a system process. 2012 */ 2013 if ((p->p_flag & SSYS) || p->p_as == &kas) { 2014 prunlock(pnp); 2015 error = EBUSY; 2016 break; 2017 } 2018 2019 if (cmd == PIOCSTOP) 2020 pr_stop(pnp); 2021 2022 /* 2023 * If an lwp is waiting for itself or its process, don't wait. 2024 * The lwp will never see the fact that itself is stopped. 2025 */ 2026 if ((pnp->pr_type == PR_LWPIDFILE)? 2027 (pcp->prc_thread == curthread) : (p == curproc)) { 2028 if (cmd == PIOCWSTOP) 2029 error = EBUSY; 2030 prunlock(pnp); 2031 break; 2032 } 2033 2034 if ((error = pr_wait_stop(pnp, (time_t)0)) != 0) 2035 break; /* pr_wait_stop() unlocked the process */ 2036 2037 if (cmaddr == NULL) 2038 prunlock(pnp); 2039 else if (PROCESS_NOT_32BIT(p)) { 2040 prunlock(pnp); 2041 error = EOVERFLOW; 2042 } else { 2043 /* 2044 * Return process/lwp status information. 2045 */ 2046 t = pr_thread(pnp); /* returns locked thread */ 2047 thread_unlock(t); 2048 oprgetstatus32(t, &un32.prstat, VTOZONE(vp)); 2049 prunlock(pnp); 2050 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat))) 2051 error = EFAULT; 2052 } 2053 break; 2054 2055 case PIOCRUN: /* make lwp or process runnable */ 2056 { 2057 long flags = un32.prrun.pr_flags; 2058 2059 /* 2060 * Cannot set an lwp running is it is not stopped. 2061 * Also, no lwp other than the /proc agent lwp can 2062 * be set running so long as the /proc agent lwp exists. 2063 */ 2064 if ((!ISTOPPED(t) && !VSTOPPED(t) && 2065 !(t->t_proc_flag & TP_PRSTOP)) || 2066 (p->p_agenttp != NULL && 2067 (t != p->p_agenttp || pnp->pr_type != PR_LWPIDFILE))) { 2068 prunlock(pnp); 2069 error = EBUSY; 2070 break; 2071 } 2072 2073 if ((flags & PRSVADDR) && PROCESS_NOT_32BIT(p)) { 2074 prunlock(pnp); 2075 error = EOVERFLOW; 2076 break; 2077 } 2078 2079 if (flags & (PRSHOLD|PRSTRACE|PRSFAULT|PRSVADDR)) { 2080 un.prrun.pr_flags = (int)flags; 2081 un.prrun.pr_trace = un32.prrun.pr_trace; 2082 un.prrun.pr_sighold = un32.prrun.pr_sighold; 2083 un.prrun.pr_fault = un32.prrun.pr_fault; 2084 un.prrun.pr_vaddr = 2085 (caddr_t)(uintptr_t)un32.prrun.pr_vaddr; 2086 prsetrun(t, &un.prrun); 2087 } 2088 2089 error = pr_setrun(pnp, prmaprunflags(flags)); 2090 2091 prunlock(pnp); 2092 break; 2093 } 2094 2095 case PIOCLWPIDS: /* get array of lwp identifiers */ 2096 { 2097 int nlwp; 2098 int Nlwp; 2099 id_t *idp; 2100 id_t *Bidp; 2101 2102 Nlwp = nlwp = p->p_lwpcnt; 2103 2104 if (thing && thingsize != (Nlwp+1) * sizeof (id_t)) { 2105 kmem_free(thing, thingsize); 2106 thing = NULL; 2107 } 2108 if (thing == NULL) { 2109 thingsize = (Nlwp+1) * sizeof (id_t); 2110 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2111 } 2112 if (thing == NULL) { 2113 prunlock(pnp); 2114 goto startover; 2115 } 2116 2117 idp = thing; 2118 thing = NULL; 2119 Bidp = idp; 2120 if ((t = p->p_tlist) != NULL) { 2121 do { 2122 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2123 ASSERT(nlwp > 0); 2124 --nlwp; 2125 *idp++ = t->t_tid; 2126 } while ((t = t->t_forw) != p->p_tlist); 2127 } 2128 *idp = 0; 2129 ASSERT(nlwp == 0); 2130 prunlock(pnp); 2131 if (copyout(Bidp, cmaddr, (Nlwp+1) * sizeof (id_t))) 2132 error = EFAULT; 2133 kmem_free(Bidp, (Nlwp+1) * sizeof (id_t)); 2134 break; 2135 } 2136 2137 case PIOCOPENLWP: /* return /proc lwp file descriptor */ 2138 { 2139 vnode_t *xvp; 2140 int n; 2141 2142 prunlock(pnp); 2143 if ((xvp = prlwpnode(pnp, un32.lwpid)) == NULL) 2144 error = ENOENT; 2145 else if (error = fassign(&xvp, flag & (FREAD|FWRITE), &n)) { 2146 VN_RELE(xvp); 2147 } else 2148 *rvalp = n; 2149 break; 2150 } 2151 2152 case PIOCOPENPD: /* return /proc page data file descriptor */ 2153 { 2154 vnode_t *xvp = PTOV(xpnp); 2155 vnode_t *dp = pnp->pr_parent; 2156 int n; 2157 2158 if (PROCESS_NOT_32BIT(p)) { 2159 prunlock(pnp); 2160 prfreenode(xpnp); 2161 xpnp = NULL; 2162 error = EOVERFLOW; 2163 break; 2164 } 2165 2166 if (pnp->pr_type == PR_LWPIDFILE) { 2167 dp = VTOP(dp)->pr_parent; 2168 dp = VTOP(dp)->pr_parent; 2169 } 2170 ASSERT(VTOP(dp)->pr_type == PR_PIDDIR); 2171 2172 VN_HOLD(dp); 2173 pcp = pnp->pr_pcommon; 2174 xpnp->pr_ino = ptoi(pcp->prc_pid); 2175 xpnp->pr_common = pcp; 2176 xpnp->pr_pcommon = pcp; 2177 xpnp->pr_parent = dp; 2178 2179 xpnp->pr_next = p->p_plist; 2180 p->p_plist = xvp; 2181 2182 prunlock(pnp); 2183 if (error = fassign(&xvp, FREAD, &n)) { 2184 VN_RELE(xvp); 2185 } else 2186 *rvalp = n; 2187 2188 xpnp = NULL; 2189 break; 2190 } 2191 2192 case PIOCGTRACE: /* get signal trace mask */ 2193 prassignset(&un32.smask, &p->p_sigmask); 2194 prunlock(pnp); 2195 if (copyout(&un32.smask, cmaddr, sizeof (un32.smask))) 2196 error = EFAULT; 2197 break; 2198 2199 case PIOCSTRACE: /* set signal trace mask */ 2200 prdelset(&un32.smask, SIGKILL); 2201 prassignset(&p->p_sigmask, &un32.smask); 2202 if (!sigisempty(&p->p_sigmask)) 2203 p->p_proc_flag |= P_PR_TRACE; 2204 else if (prisempty(&p->p_fltmask)) { 2205 up = PTOU(p); 2206 if (up->u_systrap == 0) 2207 p->p_proc_flag &= ~P_PR_TRACE; 2208 } 2209 prunlock(pnp); 2210 break; 2211 2212 case PIOCSSIG: /* set current signal */ 2213 if (un32.info.si_signo != 0 && PROCESS_NOT_32BIT(p)) { 2214 prunlock(pnp); 2215 error = EOVERFLOW; 2216 } else { 2217 bzero(&un.info, sizeof (un.info)); 2218 siginfo_32tok(&un32.info, (k_siginfo_t *)&un.info); 2219 error = pr_setsig(pnp, &un.info); 2220 prunlock(pnp); 2221 if (un32.info.si_signo == SIGKILL && error == 0) 2222 pr_wait_die(pnp); 2223 } 2224 break; 2225 2226 case PIOCKILL: /* send signal */ 2227 error = pr_kill(pnp, un32.signo, cr); 2228 prunlock(pnp); 2229 if (un32.signo == SIGKILL && error == 0) 2230 pr_wait_die(pnp); 2231 break; 2232 2233 case PIOCUNKILL: /* delete a signal */ 2234 error = pr_unkill(pnp, un32.signo); 2235 prunlock(pnp); 2236 break; 2237 2238 case PIOCNICE: /* set nice priority */ 2239 error = pr_nice(p, un32.nice, cr); 2240 prunlock(pnp); 2241 break; 2242 2243 case PIOCGENTRY: /* get syscall entry bit mask */ 2244 case PIOCGEXIT: /* get syscall exit bit mask */ 2245 up = PTOU(p); 2246 if (cmd == PIOCGENTRY) { 2247 prassignset(&un32.prmask, &up->u_entrymask); 2248 } else { 2249 prassignset(&un32.prmask, &up->u_exitmask); 2250 } 2251 prunlock(pnp); 2252 if (copyout(&un32.prmask, cmaddr, sizeof (un32.prmask))) 2253 error = EFAULT; 2254 break; 2255 2256 case PIOCSENTRY: /* set syscall entry bit mask */ 2257 case PIOCSEXIT: /* set syscall exit bit mask */ 2258 pr_setentryexit(p, &un32.prmask, cmd == PIOCSENTRY); 2259 prunlock(pnp); 2260 break; 2261 2262 case PIOCSRLC: /* obsolete: set running on last /proc close */ 2263 error = pr_set(p, prmapsetflags(PR_RLC)); 2264 prunlock(pnp); 2265 break; 2266 2267 case PIOCRRLC: /* obsolete: reset run-on-last-close flag */ 2268 error = pr_unset(p, prmapsetflags(PR_RLC)); 2269 prunlock(pnp); 2270 break; 2271 2272 case PIOCSFORK: /* obsolete: set inherit-on-fork flag */ 2273 error = pr_set(p, prmapsetflags(PR_FORK)); 2274 prunlock(pnp); 2275 break; 2276 2277 case PIOCRFORK: /* obsolete: reset inherit-on-fork flag */ 2278 error = pr_unset(p, prmapsetflags(PR_FORK)); 2279 prunlock(pnp); 2280 break; 2281 2282 case PIOCSET: /* set process flags */ 2283 error = pr_set(p, prmapsetflags((long)un32.flags)); 2284 prunlock(pnp); 2285 break; 2286 2287 case PIOCRESET: /* reset process flags */ 2288 error = pr_unset(p, prmapsetflags((long)un32.flags)); 2289 prunlock(pnp); 2290 break; 2291 2292 case PIOCGREG: /* get general registers */ 2293 if (PROCESS_NOT_32BIT(p)) 2294 error = EOVERFLOW; 2295 else if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 2296 bzero(un32.regs, sizeof (un32.regs)); 2297 else { 2298 /* drop p_lock while touching the lwp's stack */ 2299 mutex_exit(&p->p_lock); 2300 prgetprregs32(lwp, un32.regs); 2301 mutex_enter(&p->p_lock); 2302 } 2303 prunlock(pnp); 2304 if (error == 0 && 2305 copyout(un32.regs, cmaddr, sizeof (un32.regs))) 2306 error = EFAULT; 2307 break; 2308 2309 case PIOCSREG: /* set general registers */ 2310 if (PROCESS_NOT_32BIT(p)) 2311 error = EOVERFLOW; 2312 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 2313 error = EBUSY; 2314 else { 2315 /* drop p_lock while touching the lwp's stack */ 2316 mutex_exit(&p->p_lock); 2317 prgregset_32ton(lwp, un32.regs, un.regs); 2318 prsetprregs(lwp, un.regs, 0); 2319 mutex_enter(&p->p_lock); 2320 } 2321 prunlock(pnp); 2322 break; 2323 2324 case PIOCGFPREG: /* get floating-point registers */ 2325 if (!prhasfp()) 2326 error = EINVAL; /* No FP support */ 2327 else if (PROCESS_NOT_32BIT(p)) 2328 error = EOVERFLOW; 2329 else if (t->t_state != TS_STOPPED && !VSTOPPED(t)) 2330 bzero(&un32.fpregs, sizeof (un32.fpregs)); 2331 else { 2332 /* drop p_lock while touching the lwp's stack */ 2333 mutex_exit(&p->p_lock); 2334 prgetprfpregs32(lwp, &un32.fpregs); 2335 mutex_enter(&p->p_lock); 2336 } 2337 prunlock(pnp); 2338 if (error == 0 && 2339 copyout(&un32.fpregs, cmaddr, sizeof (un32.fpregs))) 2340 error = EFAULT; 2341 break; 2342 2343 case PIOCSFPREG: /* set floating-point registers */ 2344 if (!prhasfp()) 2345 error = EINVAL; /* No FP support */ 2346 else if (PROCESS_NOT_32BIT(p)) 2347 error = EOVERFLOW; 2348 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t)) 2349 error = EBUSY; 2350 else { 2351 /* drop p_lock while touching the lwp's stack */ 2352 mutex_exit(&p->p_lock); 2353 prsetprfpregs32(lwp, &un32.fpregs); 2354 mutex_enter(&p->p_lock); 2355 } 2356 prunlock(pnp); 2357 break; 2358 2359 case PIOCGXREGSIZE: /* get the size of the extra registers */ 2360 { 2361 if (prhasx(p)) { 2362 size_t xregsize; 2363 int abisize; 2364 2365 xregsize = prgetprxregsize(p); 2366 prunlock(pnp); 2367 if (xregsize > INT_MAX) { 2368 error = EOVERFLOW; 2369 break; 2370 } 2371 2372 abisize = (int)xregsize; 2373 if (copyout(&abisize, cmaddr, sizeof (abisize))) 2374 error = EFAULT; 2375 } else { 2376 prunlock(pnp); 2377 error = EINVAL; /* No extra register support */ 2378 } 2379 break; 2380 } 2381 2382 case PIOCGXREG: /* get extra registers */ 2383 if (PROCESS_NOT_32BIT(p)) 2384 error = EOVERFLOW; 2385 else if (!prhasx(p)) 2386 error = EINVAL; /* No extra register support */ 2387 else { 2388 bzero(thing, thingsize); 2389 if (t->t_state == TS_STOPPED || VSTOPPED(t)) { 2390 /* drop p_lock to touch the stack */ 2391 mutex_exit(&p->p_lock); 2392 prgetprxregs(lwp, thing); 2393 mutex_enter(&p->p_lock); 2394 } 2395 } 2396 prunlock(pnp); 2397 if (error == 0 && 2398 copyout(thing, cmaddr, thingsize)) 2399 error = EFAULT; 2400 if (thing) { 2401 kmem_free(thing, thingsize); 2402 thing = NULL; 2403 } 2404 break; 2405 2406 case PIOCSTATUS: /* get process/lwp status */ 2407 if (PROCESS_NOT_32BIT(p)) { 2408 prunlock(pnp); 2409 error = EOVERFLOW; 2410 break; 2411 } 2412 oprgetstatus32(t, &un32.prstat, VTOZONE(vp)); 2413 prunlock(pnp); 2414 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat))) 2415 error = EFAULT; 2416 break; 2417 2418 case PIOCLSTATUS: /* get status for process & all lwps */ 2419 { 2420 int Nlwp; 2421 int nlwp; 2422 prstatus32_t *Bprsp; 2423 prstatus32_t *prsp; 2424 2425 if (PROCESS_NOT_32BIT(p)) { 2426 prunlock(pnp); 2427 if (thing) { 2428 kmem_free(thing, thingsize); 2429 thing = NULL; 2430 } 2431 error = EOVERFLOW; 2432 break; 2433 } 2434 2435 nlwp = Nlwp = p->p_lwpcnt; 2436 2437 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus32_t)) { 2438 kmem_free(thing, thingsize); 2439 thing = NULL; 2440 } 2441 if (thing == NULL) { 2442 thingsize = (Nlwp+1) * sizeof (prstatus32_t); 2443 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2444 } 2445 if (thing == NULL) { 2446 prunlock(pnp); 2447 goto startover; 2448 } 2449 2450 Bprsp = (prstatus32_t *)thing; 2451 thing = NULL; 2452 prsp = Bprsp; 2453 oprgetstatus32(t, prsp, VTOZONE(vp)); 2454 t = p->p_tlist; 2455 do { 2456 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2457 ASSERT(nlwp > 0); 2458 --nlwp; 2459 oprgetstatus32(t, ++prsp, VTOZONE(vp)); 2460 } while ((t = t->t_forw) != p->p_tlist); 2461 ASSERT(nlwp == 0); 2462 prunlock(pnp); 2463 if (copyout(Bprsp, cmaddr, (Nlwp+1) * sizeof (prstatus32_t))) 2464 error = EFAULT; 2465 2466 kmem_free(Bprsp, (Nlwp + 1) * sizeof (prstatus32_t)); 2467 break; 2468 } 2469 2470 case PIOCPSINFO: /* get ps(1) information */ 2471 { 2472 prpsinfo32_t *psp = &un32.prps; 2473 2474 oprgetpsinfo32(p, psp, 2475 (pnp->pr_type == PR_LWPIDFILE)? pcp->prc_thread : NULL); 2476 2477 prunlock(pnp); 2478 if (copyout(&un32.prps, cmaddr, sizeof (un32.prps))) 2479 error = EFAULT; 2480 break; 2481 } 2482 2483 case PIOCMAXSIG: /* get maximum signal number */ 2484 { 2485 int n = nsig-1; 2486 2487 prunlock(pnp); 2488 if (copyout(&n, cmaddr, sizeof (int))) 2489 error = EFAULT; 2490 break; 2491 } 2492 2493 case PIOCACTION: /* get signal action structures */ 2494 { 2495 uint_t sig; 2496 struct sigaction32 *sap = thing; 2497 2498 if (PROCESS_NOT_32BIT(p)) 2499 error = EOVERFLOW; 2500 else { 2501 up = PTOU(p); 2502 for (sig = 1; sig < nsig; sig++) 2503 prgetaction32(p, up, sig, &sap[sig-1]); 2504 } 2505 prunlock(pnp); 2506 if (error == 0 && 2507 copyout(sap, cmaddr, (nsig-1)*sizeof (struct sigaction32))) 2508 error = EFAULT; 2509 kmem_free(sap, (nsig-1)*sizeof (struct sigaction32)); 2510 thing = NULL; 2511 break; 2512 } 2513 2514 case PIOCGHOLD: /* get signal-hold mask */ 2515 prgethold(t, &un32.holdmask); 2516 prunlock(pnp); 2517 if (copyout(&un32.holdmask, cmaddr, sizeof (un32.holdmask))) 2518 error = EFAULT; 2519 break; 2520 2521 case PIOCSHOLD: /* set signal-hold mask */ 2522 pr_sethold(pnp, &un32.holdmask); 2523 prunlock(pnp); 2524 break; 2525 2526 case PIOCNMAP: /* get number of memory mappings */ 2527 { 2528 uint_t n; 2529 struct as *as = p->p_as; 2530 2531 if ((p->p_flag & SSYS) || as == &kas) 2532 n = 0; 2533 else { 2534 mutex_exit(&p->p_lock); 2535 AS_LOCK_ENTER(as, RW_WRITER); 2536 n = prnsegs(as, 0); 2537 AS_LOCK_EXIT(as); 2538 mutex_enter(&p->p_lock); 2539 } 2540 prunlock(pnp); 2541 if (copyout(&n, cmaddr, sizeof (uint_t))) 2542 error = EFAULT; 2543 break; 2544 } 2545 2546 case PIOCMAP: /* get memory map information */ 2547 { 2548 list_t iolhead; 2549 struct as *as = p->p_as; 2550 2551 if ((p->p_flag & SSYS) || as == &kas) { 2552 error = 0; 2553 prunlock(pnp); 2554 } else if (PROCESS_NOT_32BIT(p)) { 2555 error = EOVERFLOW; 2556 prunlock(pnp); 2557 } else { 2558 mutex_exit(&p->p_lock); 2559 AS_LOCK_ENTER(as, RW_WRITER); 2560 error = oprgetmap32(p, &iolhead); 2561 AS_LOCK_EXIT(as); 2562 mutex_enter(&p->p_lock); 2563 prunlock(pnp); 2564 2565 error = pr_iol_copyout_and_free(&iolhead, 2566 &cmaddr, error); 2567 } 2568 /* 2569 * The procfs PIOCMAP ioctl returns an all-zero buffer 2570 * to indicate the end of the prmap[] array. 2571 * Append it to whatever has already been copied out. 2572 */ 2573 bzero(&un32.prmap, sizeof (un32.prmap)); 2574 if (!error && 2575 copyout(&un32.prmap, cmaddr, sizeof (un32.prmap))) 2576 error = EFAULT; 2577 break; 2578 } 2579 2580 case PIOCGFAULT: /* get mask of traced faults */ 2581 prassignset(&un32.fltmask, &p->p_fltmask); 2582 prunlock(pnp); 2583 if (copyout(&un32.fltmask, cmaddr, sizeof (un32.fltmask))) 2584 error = EFAULT; 2585 break; 2586 2587 case PIOCSFAULT: /* set mask of traced faults */ 2588 pr_setfault(p, &un32.fltmask); 2589 prunlock(pnp); 2590 break; 2591 2592 case PIOCCFAULT: /* clear current fault */ 2593 lwp->lwp_curflt = 0; 2594 prunlock(pnp); 2595 break; 2596 2597 case PIOCCRED: /* get process credentials */ 2598 { 2599 cred_t *cp; 2600 2601 mutex_enter(&p->p_crlock); 2602 cp = p->p_cred; 2603 un32.prcred.pr_euid = crgetuid(cp); 2604 un32.prcred.pr_ruid = crgetruid(cp); 2605 un32.prcred.pr_suid = crgetsuid(cp); 2606 un32.prcred.pr_egid = crgetgid(cp); 2607 un32.prcred.pr_rgid = crgetrgid(cp); 2608 un32.prcred.pr_sgid = crgetsgid(cp); 2609 un32.prcred.pr_ngroups = crgetngroups(cp); 2610 mutex_exit(&p->p_crlock); 2611 2612 prunlock(pnp); 2613 if (copyout(&un32.prcred, cmaddr, sizeof (un32.prcred))) 2614 error = EFAULT; 2615 break; 2616 } 2617 2618 case PIOCGROUPS: /* get supplementary groups */ 2619 { 2620 cred_t *cp; 2621 2622 mutex_enter(&p->p_crlock); 2623 cp = p->p_cred; 2624 crhold(cp); 2625 mutex_exit(&p->p_crlock); 2626 2627 prunlock(pnp); 2628 if (copyout(crgetgroups(cp), cmaddr, 2629 MAX(crgetngroups(cp), 1) * sizeof (gid_t))) 2630 error = EFAULT; 2631 crfree(cp); 2632 break; 2633 } 2634 2635 case PIOCUSAGE: /* get usage info */ 2636 { 2637 /* 2638 * For an lwp file descriptor, return just the lwp usage. 2639 * For a process file descriptor, return total usage, 2640 * all current lwps plus all defunct lwps. 2641 */ 2642 prhusage_t *pup = &un32.prhusage; 2643 prusage32_t *upup; 2644 2645 bzero(pup, sizeof (*pup)); 2646 pup->pr_tstamp = gethrtime(); 2647 2648 if (pnp->pr_type == PR_LWPIDFILE) { 2649 t = pcp->prc_thread; 2650 if (t != NULL) 2651 prgetusage(t, pup); 2652 else 2653 error = ENOENT; 2654 } else { 2655 pup->pr_count = p->p_defunct; 2656 pup->pr_create = p->p_mstart; 2657 pup->pr_term = p->p_mterm; 2658 2659 pup->pr_rtime = p->p_mlreal; 2660 pup->pr_utime = p->p_acct[LMS_USER]; 2661 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 2662 pup->pr_ttime = p->p_acct[LMS_TRAP]; 2663 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 2664 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 2665 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 2666 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 2667 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 2668 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 2669 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 2670 2671 pup->pr_minf = p->p_ru.minflt; 2672 pup->pr_majf = p->p_ru.majflt; 2673 pup->pr_nswap = p->p_ru.nswap; 2674 pup->pr_inblk = p->p_ru.inblock; 2675 pup->pr_oublk = p->p_ru.oublock; 2676 pup->pr_msnd = p->p_ru.msgsnd; 2677 pup->pr_mrcv = p->p_ru.msgrcv; 2678 pup->pr_sigs = p->p_ru.nsignals; 2679 pup->pr_vctx = p->p_ru.nvcsw; 2680 pup->pr_ictx = p->p_ru.nivcsw; 2681 pup->pr_sysc = p->p_ru.sysc; 2682 pup->pr_ioch = p->p_ru.ioch; 2683 2684 /* 2685 * Add the usage information for each active lwp. 2686 */ 2687 if ((t = p->p_tlist) != NULL && 2688 !(pcp->prc_flags & PRC_DESTROY)) { 2689 do { 2690 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2691 pup->pr_count++; 2692 praddusage(t, pup); 2693 } while ((t = t->t_forw) != p->p_tlist); 2694 } 2695 } 2696 2697 prunlock(pnp); 2698 2699 upup = kmem_alloc(sizeof (*upup), KM_SLEEP); 2700 prcvtusage32(pup, upup); 2701 if (copyout(upup, cmaddr, sizeof (*upup))) 2702 error = EFAULT; 2703 kmem_free(upup, sizeof (*upup)); 2704 2705 break; 2706 } 2707 2708 case PIOCLUSAGE: /* get detailed usage info */ 2709 { 2710 int Nlwp; 2711 int nlwp; 2712 prusage32_t *upup; 2713 prusage32_t *Bupup; 2714 prhusage_t *pup; 2715 hrtime_t curtime; 2716 2717 nlwp = Nlwp = (pcp->prc_flags & PRC_DESTROY)? 0 : p->p_lwpcnt; 2718 2719 if (thing && thingsize != 2720 sizeof (prhusage_t) + (Nlwp+1) * sizeof (prusage32_t)) { 2721 kmem_free(thing, thingsize); 2722 thing = NULL; 2723 } 2724 if (thing == NULL) { 2725 thingsize = sizeof (prhusage_t) + 2726 (Nlwp+1) * sizeof (prusage32_t); 2727 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2728 } 2729 if (thing == NULL) { 2730 prunlock(pnp); 2731 goto startover; 2732 } 2733 2734 pup = (prhusage_t *)thing; 2735 upup = Bupup = (prusage32_t *)(pup + 1); 2736 2737 ASSERT(p == pcp->prc_proc); 2738 2739 curtime = gethrtime(); 2740 2741 /* 2742 * First the summation over defunct lwps. 2743 */ 2744 bzero(pup, sizeof (*pup)); 2745 pup->pr_count = p->p_defunct; 2746 pup->pr_tstamp = curtime; 2747 pup->pr_create = p->p_mstart; 2748 pup->pr_term = p->p_mterm; 2749 2750 pup->pr_rtime = p->p_mlreal; 2751 pup->pr_utime = p->p_acct[LMS_USER]; 2752 pup->pr_stime = p->p_acct[LMS_SYSTEM]; 2753 pup->pr_ttime = p->p_acct[LMS_TRAP]; 2754 pup->pr_tftime = p->p_acct[LMS_TFAULT]; 2755 pup->pr_dftime = p->p_acct[LMS_DFAULT]; 2756 pup->pr_kftime = p->p_acct[LMS_KFAULT]; 2757 pup->pr_ltime = p->p_acct[LMS_USER_LOCK]; 2758 pup->pr_slptime = p->p_acct[LMS_SLEEP]; 2759 pup->pr_wtime = p->p_acct[LMS_WAIT_CPU]; 2760 pup->pr_stoptime = p->p_acct[LMS_STOPPED]; 2761 2762 pup->pr_minf = p->p_ru.minflt; 2763 pup->pr_majf = p->p_ru.majflt; 2764 pup->pr_nswap = p->p_ru.nswap; 2765 pup->pr_inblk = p->p_ru.inblock; 2766 pup->pr_oublk = p->p_ru.oublock; 2767 pup->pr_msnd = p->p_ru.msgsnd; 2768 pup->pr_mrcv = p->p_ru.msgrcv; 2769 pup->pr_sigs = p->p_ru.nsignals; 2770 pup->pr_vctx = p->p_ru.nvcsw; 2771 pup->pr_ictx = p->p_ru.nivcsw; 2772 pup->pr_sysc = p->p_ru.sysc; 2773 pup->pr_ioch = p->p_ru.ioch; 2774 2775 prcvtusage32(pup, upup); 2776 2777 /* 2778 * Fill one prusage struct for each active lwp. 2779 */ 2780 if ((t = p->p_tlist) != NULL && 2781 !(pcp->prc_flags & PRC_DESTROY)) { 2782 do { 2783 ASSERT(!(t->t_proc_flag & TP_LWPEXIT)); 2784 ASSERT(nlwp > 0); 2785 --nlwp; 2786 upup++; 2787 prgetusage(t, pup); 2788 prcvtusage32(pup, upup); 2789 } while ((t = t->t_forw) != p->p_tlist); 2790 } 2791 ASSERT(nlwp == 0); 2792 2793 prunlock(pnp); 2794 if (copyout(Bupup, cmaddr, (Nlwp+1) * sizeof (prusage32_t))) 2795 error = EFAULT; 2796 kmem_free(thing, thingsize); 2797 thing = NULL; 2798 break; 2799 } 2800 2801 case PIOCNAUXV: /* get number of aux vector entries */ 2802 { 2803 int n = __KERN_NAUXV_IMPL; 2804 2805 prunlock(pnp); 2806 if (copyout(&n, cmaddr, sizeof (int))) 2807 error = EFAULT; 2808 break; 2809 } 2810 2811 case PIOCAUXV: /* get aux vector (see sys/auxv.h) */ 2812 { 2813 int i; 2814 2815 if (PROCESS_NOT_32BIT(p)) { 2816 prunlock(pnp); 2817 error = EOVERFLOW; 2818 } else { 2819 up = PTOU(p); 2820 for (i = 0; i < __KERN_NAUXV_IMPL; i++) { 2821 un32.auxv[i].a_type = up->u_auxv[i].a_type; 2822 un32.auxv[i].a_un.a_val = 2823 (int32_t)up->u_auxv[i].a_un.a_val; 2824 } 2825 prunlock(pnp); 2826 if (copyout(un32.auxv, cmaddr, 2827 __KERN_NAUXV_IMPL * sizeof (auxv32_t))) 2828 error = EFAULT; 2829 } 2830 break; 2831 } 2832 2833 #if defined(__i386_COMPAT) 2834 case PIOCNLDT: /* get number of LDT entries */ 2835 { 2836 int n; 2837 2838 mutex_exit(&p->p_lock); 2839 mutex_enter(&p->p_ldtlock); 2840 n = prnldt(p); 2841 mutex_exit(&p->p_ldtlock); 2842 mutex_enter(&p->p_lock); 2843 prunlock(pnp); 2844 if (copyout(&n, cmaddr, sizeof (n))) 2845 error = EFAULT; 2846 break; 2847 } 2848 2849 case PIOCLDT: /* get LDT entries */ 2850 { 2851 struct ssd *ssd; 2852 int n; 2853 2854 mutex_exit(&p->p_lock); 2855 mutex_enter(&p->p_ldtlock); 2856 n = prnldt(p); 2857 2858 if (thing && thingsize != (n+1) * sizeof (*ssd)) { 2859 kmem_free(thing, thingsize); 2860 thing = NULL; 2861 } 2862 if (thing == NULL) { 2863 thingsize = (n+1) * sizeof (*ssd); 2864 thing = kmem_alloc(thingsize, KM_NOSLEEP); 2865 } 2866 if (thing == NULL) { 2867 mutex_exit(&p->p_ldtlock); 2868 mutex_enter(&p->p_lock); 2869 prunlock(pnp); 2870 goto startover; 2871 } 2872 2873 ssd = thing; 2874 thing = NULL; 2875 if (n != 0) 2876 prgetldt(p, ssd); 2877 mutex_exit(&p->p_ldtlock); 2878 mutex_enter(&p->p_lock); 2879 prunlock(pnp); 2880 2881 /* mark the end of the list with a null entry */ 2882 bzero(&ssd[n], sizeof (*ssd)); 2883 if (copyout(ssd, cmaddr, (n+1) * sizeof (*ssd))) 2884 error = EFAULT; 2885 kmem_free(ssd, (n+1) * sizeof (*ssd)); 2886 break; 2887 } 2888 #endif /* __i386_COMPAT */ 2889 2890 #if defined(__sparc) 2891 case PIOCGWIN: /* get gwindows_t (see sys/reg.h) */ 2892 { 2893 gwindows32_t *gwp = thing; 2894 2895 if (PROCESS_NOT_32BIT(p)) { 2896 prunlock(pnp); 2897 error = EOVERFLOW; 2898 } else { 2899 /* drop p->p_lock while touching the stack */ 2900 mutex_exit(&p->p_lock); 2901 bzero(gwp, sizeof (*gwp)); 2902 prgetwindows32(lwp, gwp); 2903 mutex_enter(&p->p_lock); 2904 prunlock(pnp); 2905 if (copyout(gwp, cmaddr, sizeof (*gwp))) 2906 error = EFAULT; 2907 } 2908 kmem_free(gwp, sizeof (*gwp)); 2909 thing = NULL; 2910 break; 2911 } 2912 #endif /* __sparc */ 2913 2914 default: 2915 prunlock(pnp); 2916 error = EINVAL; 2917 break; 2918 2919 } 2920 2921 ASSERT(thing == NULL); 2922 ASSERT(xpnp == NULL); 2923 return (error); 2924 } 2925 #endif /* _SYSCALL32_IMPL */ 2926 2927 /* 2928 * Distinguish "writeable" ioctl requests from others. 2929 */ 2930 static int 2931 isprwrioctl(int cmd) 2932 { 2933 switch (cmd) { 2934 case PIOCSTOP: 2935 case PIOCRUN: 2936 case PIOCSTRACE: 2937 case PIOCSSIG: 2938 case PIOCKILL: 2939 case PIOCUNKILL: 2940 case PIOCNICE: 2941 case PIOCSENTRY: 2942 case PIOCSEXIT: 2943 case PIOCSRLC: 2944 case PIOCRRLC: 2945 case PIOCSREG: 2946 case PIOCSFPREG: 2947 case PIOCSXREG: 2948 case PIOCSHOLD: 2949 case PIOCSFAULT: 2950 case PIOCCFAULT: 2951 case PIOCSFORK: 2952 case PIOCRFORK: 2953 case PIOCSET: 2954 case PIOCRESET: 2955 return (1); 2956 } 2957 return (0); 2958 } 2959 2960 /* 2961 * Map the ioctl() interface run flags to the new interface run flags. 2962 */ 2963 static ulong_t 2964 prmaprunflags(long flags) 2965 { 2966 ulong_t newflags = 0; 2967 2968 if (flags & PRCSIG) 2969 newflags |= 0x01; 2970 if (flags & PRCFAULT) 2971 newflags |= 0x02; 2972 if (flags & PRSTEP) 2973 newflags |= 0x04; 2974 if (flags & PRSABORT) 2975 newflags |= 0x08; 2976 if (flags & PRSTOP) 2977 newflags |= 0x10; 2978 return (newflags); 2979 } 2980 2981 /* 2982 * Map the ioctl() interface settable mode flags to the new interface flags. 2983 */ 2984 static long 2985 prmapsetflags(long flags) 2986 { 2987 long newflags = 0; 2988 2989 #define ALLFLAGS \ 2990 (PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_MSACCT|PR_PCOMPAT) 2991 2992 if (flags & ~ALLFLAGS) 2993 newflags = 0xffff; /* forces EINVAL */ 2994 if (flags & PR_FORK) 2995 newflags |= (0x00100000 | 0x08000000); 2996 if (flags & PR_RLC) 2997 newflags |= 0x00200000; 2998 if (flags & PR_KLC) 2999 newflags |= 0x00400000; 3000 if (flags & PR_ASYNC) 3001 newflags |= 0x00800000; 3002 if (flags & PR_MSACCT) 3003 newflags |= 0x01000000; 3004 if (flags & PR_BPTADJ) 3005 newflags |= 0x02000000; 3006 if (flags & PR_PCOMPAT) 3007 newflags |= 0x04000000; 3008 return (newflags); 3009 } 3010 3011 /* 3012 * Apply PIOCRUN options specific to the ioctl() interface. 3013 */ 3014 static void 3015 prsetrun(kthread_t *t, prrun_t *prp) 3016 { 3017 proc_t *p = ttoproc(t); 3018 klwp_t *lwp = ttolwp(t); 3019 long flags = prp->pr_flags; 3020 user_t *up = PTOU(p); 3021 3022 ASSERT(MUTEX_HELD(&p->p_lock)); 3023 3024 if (flags & PRSHOLD) { 3025 schedctl_finish_sigblock(t); 3026 sigutok(&prp->pr_sighold, &t->t_hold); 3027 t->t_sig_check = 1; /* so ISSIG will be done */ 3028 } 3029 if (flags & PRSTRACE) { 3030 prdelset(&prp->pr_trace, SIGKILL); 3031 prassignset(&p->p_sigmask, &prp->pr_trace); 3032 if (!sigisempty(&p->p_sigmask)) 3033 p->p_proc_flag |= P_PR_TRACE; 3034 else if (prisempty(&p->p_fltmask)) { 3035 if (up->u_systrap == 0) 3036 p->p_proc_flag &= ~P_PR_TRACE; 3037 } 3038 } 3039 if (flags & PRSFAULT) { 3040 prassignset(&p->p_fltmask, &prp->pr_fault); 3041 if (!prisempty(&p->p_fltmask)) 3042 p->p_proc_flag |= P_PR_TRACE; 3043 else if (sigisempty(&p->p_sigmask)) { 3044 if (up->u_systrap == 0) 3045 p->p_proc_flag &= ~P_PR_TRACE; 3046 } 3047 } 3048 /* 3049 * prsvaddr() must be called before prstep() because 3050 * stepping can depend on the current value of the PC. 3051 * We drop p_lock while touching the lwp's registers (on stack). 3052 */ 3053 if (flags & PRSVADDR) { 3054 mutex_exit(&p->p_lock); 3055 prsvaddr(lwp, prp->pr_vaddr); 3056 mutex_enter(&p->p_lock); 3057 } 3058 } 3059 3060 /* 3061 * Common code for PIOCOPENM 3062 * Returns with the process unlocked. 3063 */ 3064 static int 3065 propenm(prnode_t *pnp, caddr_t cmaddr, caddr_t va, int *rvalp, cred_t *cr) 3066 { 3067 proc_t *p = pnp->pr_common->prc_proc; 3068 struct as *as = p->p_as; 3069 int error = 0; 3070 struct seg *seg; 3071 struct vnode *xvp; 3072 int n; 3073 3074 /* 3075 * By fiat, a system process has no address space. 3076 */ 3077 if ((p->p_flag & SSYS) || as == &kas) { 3078 error = EINVAL; 3079 } else if (cmaddr) { 3080 /* 3081 * We drop p_lock before grabbing the address 3082 * space lock in order to avoid a deadlock with 3083 * the clock thread. The process will not 3084 * disappear and its address space will not 3085 * change because it is marked P_PR_LOCK. 3086 */ 3087 mutex_exit(&p->p_lock); 3088 AS_LOCK_ENTER(as, RW_READER); 3089 seg = as_segat(as, va); 3090 if (seg != NULL && 3091 seg->s_ops == &segvn_ops && 3092 SEGOP_GETVP(seg, va, &xvp) == 0 && 3093 xvp != NULL && 3094 xvp->v_type == VREG) { 3095 VN_HOLD(xvp); 3096 } else { 3097 error = EINVAL; 3098 } 3099 AS_LOCK_EXIT(as); 3100 mutex_enter(&p->p_lock); 3101 } else if ((xvp = p->p_exec) == NULL) { 3102 error = EINVAL; 3103 } else { 3104 VN_HOLD(xvp); 3105 } 3106 3107 prunlock(pnp); 3108 3109 if (error == 0) { 3110 if ((error = VOP_ACCESS(xvp, VREAD, 0, cr, NULL)) == 0) 3111 error = fassign(&xvp, FREAD, &n); 3112 if (error) { 3113 VN_RELE(xvp); 3114 } else { 3115 *rvalp = n; 3116 } 3117 } 3118 3119 return (error); 3120 } 3121 3122 /* 3123 * Return old version of process/lwp status. 3124 * The u-block is mapped in by this routine and unmapped at the end. 3125 */ 3126 void 3127 oprgetstatus(kthread_t *t, prstatus_t *sp, zone_t *zp) 3128 { 3129 proc_t *p = ttoproc(t); 3130 klwp_t *lwp = ttolwp(t); 3131 int flags; 3132 user_t *up; 3133 ulong_t instr; 3134 3135 ASSERT(MUTEX_HELD(&p->p_lock)); 3136 3137 up = PTOU(p); 3138 bzero(sp, sizeof (*sp)); 3139 flags = 0; 3140 if (t->t_state == TS_STOPPED) { 3141 flags |= PR_STOPPED; 3142 if ((t->t_schedflag & TS_PSTART) == 0) 3143 flags |= PR_ISTOP; 3144 } else if (VSTOPPED(t)) { 3145 flags |= PR_STOPPED|PR_ISTOP; 3146 } 3147 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP)) 3148 flags |= PR_DSTOP; 3149 if (lwp->lwp_asleep) 3150 flags |= PR_ASLEEP; 3151 if (p->p_proc_flag & P_PR_FORK) 3152 flags |= PR_FORK; 3153 if (p->p_proc_flag & P_PR_RUNLCL) 3154 flags |= PR_RLC; 3155 if (p->p_proc_flag & P_PR_KILLCL) 3156 flags |= PR_KLC; 3157 if (p->p_proc_flag & P_PR_ASYNC) 3158 flags |= PR_ASYNC; 3159 if (p->p_proc_flag & P_PR_BPTADJ) 3160 flags |= PR_BPTADJ; 3161 if (p->p_proc_flag & P_PR_PTRACE) 3162 flags |= PR_PCOMPAT; 3163 if (t->t_proc_flag & TP_MSACCT) 3164 flags |= PR_MSACCT; 3165 sp->pr_flags = flags; 3166 if (VSTOPPED(t)) { 3167 sp->pr_why = PR_REQUESTED; 3168 sp->pr_what = 0; 3169 } else { 3170 sp->pr_why = t->t_whystop; 3171 sp->pr_what = t->t_whatstop; 3172 } 3173 3174 if (t->t_whystop == PR_FAULTED) 3175 bcopy(&lwp->lwp_siginfo, 3176 &sp->pr_info, sizeof (k_siginfo_t)); 3177 else if (lwp->lwp_curinfo) 3178 bcopy(&lwp->lwp_curinfo->sq_info, 3179 &sp->pr_info, sizeof (k_siginfo_t)); 3180 3181 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID && 3182 sp->pr_info.si_zoneid != zp->zone_id) { 3183 sp->pr_info.si_pid = zp->zone_zsched->p_pid; 3184 sp->pr_info.si_uid = 0; 3185 sp->pr_info.si_ctid = -1; 3186 sp->pr_info.si_zoneid = zp->zone_id; 3187 } 3188 3189 sp->pr_cursig = lwp->lwp_cursig; 3190 prassignset(&sp->pr_sigpend, &p->p_sig); 3191 prassignset(&sp->pr_lwppend, &t->t_sig); 3192 prgethold(t, &sp->pr_sighold); 3193 sp->pr_altstack = lwp->lwp_sigaltstack; 3194 prgetaction(p, up, lwp->lwp_cursig, &sp->pr_action); 3195 sp->pr_pid = p->p_pid; 3196 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 3197 (p->p_flag & SZONETOP)) { 3198 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 3199 /* 3200 * Inside local zones, fake zsched's pid as parent pids for 3201 * processes which reference processes outside of the zone. 3202 */ 3203 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 3204 } else { 3205 sp->pr_ppid = p->p_ppid; 3206 } 3207 sp->pr_pgrp = p->p_pgrp; 3208 sp->pr_sid = p->p_sessp->s_sid; 3209 hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime); 3210 hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime); 3211 TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime); 3212 TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime); 3213 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name, 3214 sizeof (sp->pr_clname) - 1); 3215 sp->pr_who = t->t_tid; 3216 sp->pr_nlwp = p->p_lwpcnt; 3217 sp->pr_brkbase = p->p_brkbase; 3218 sp->pr_brksize = p->p_brksize; 3219 sp->pr_stkbase = prgetstackbase(p); 3220 sp->pr_stksize = p->p_stksize; 3221 sp->pr_oldcontext = (struct ucontext *)lwp->lwp_oldcontext; 3222 sp->pr_processor = t->t_cpu->cpu_id; 3223 sp->pr_bind = t->t_bind_cpu; 3224 3225 /* 3226 * Fetch the current instruction, if not a system process. 3227 * We don't attempt this unless the lwp is stopped. 3228 */ 3229 if ((p->p_flag & SSYS) || p->p_as == &kas) 3230 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL); 3231 else if (!(flags & PR_STOPPED)) 3232 sp->pr_flags |= PR_PCINVAL; 3233 else if (!prfetchinstr(lwp, &instr)) 3234 sp->pr_flags |= PR_PCINVAL; 3235 else 3236 sp->pr_instr = instr; 3237 3238 /* 3239 * Drop p_lock while touching the lwp's stack. 3240 */ 3241 mutex_exit(&p->p_lock); 3242 if (prisstep(lwp)) 3243 sp->pr_flags |= PR_STEP; 3244 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) { 3245 int i; 3246 auxv_t *auxp; 3247 3248 sp->pr_syscall = get_syscall_args(lwp, 3249 (long *)sp->pr_sysarg, &i); 3250 sp->pr_nsysarg = (short)i; 3251 if (t->t_whystop == PR_SYSEXIT && t->t_sysnum == SYS_execve) { 3252 sp->pr_sysarg[0] = 0; 3253 sp->pr_sysarg[1] = (uintptr_t)up->u_argv; 3254 sp->pr_sysarg[2] = (uintptr_t)up->u_envp; 3255 for (i = 0, auxp = up->u_auxv; 3256 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]); 3257 i++, auxp++) { 3258 if (auxp->a_type == AT_SUN_EXECNAME) { 3259 sp->pr_sysarg[0] = 3260 (uintptr_t)auxp->a_un.a_ptr; 3261 break; 3262 } 3263 } 3264 } 3265 } 3266 if ((flags & PR_STOPPED) || t == curthread) 3267 prgetprregs(lwp, sp->pr_reg); 3268 mutex_enter(&p->p_lock); 3269 } 3270 3271 /* 3272 * Return old version of information used by ps(1). 3273 */ 3274 void 3275 oprgetpsinfo(proc_t *p, prpsinfo_t *psp, kthread_t *tp) 3276 { 3277 kthread_t *t; 3278 char c, state; 3279 user_t *up; 3280 dev_t d; 3281 uint64_t pct; 3282 int retval, niceval; 3283 cred_t *cred; 3284 struct as *as; 3285 hrtime_t hrutime, hrstime, cur_time; 3286 3287 ASSERT(MUTEX_HELD(&p->p_lock)); 3288 3289 bzero(psp, sizeof (*psp)); 3290 3291 if ((t = tp) == NULL) 3292 t = prchoose(p); /* returns locked thread */ 3293 else 3294 thread_lock(t); 3295 3296 /* kludge: map thread state enum into process state enum */ 3297 3298 if (t == NULL) { 3299 state = TS_ZOMB; 3300 } else { 3301 state = VSTOPPED(t) ? TS_STOPPED : t->t_state; 3302 thread_unlock(t); 3303 } 3304 3305 switch (state) { 3306 case TS_SLEEP: state = SSLEEP; break; 3307 case TS_RUN: state = SRUN; break; 3308 case TS_ONPROC: state = SONPROC; break; 3309 case TS_ZOMB: state = SZOMB; break; 3310 case TS_STOPPED: state = SSTOP; break; 3311 default: state = 0; break; 3312 } 3313 switch (state) { 3314 case SSLEEP: c = 'S'; break; 3315 case SRUN: c = 'R'; break; 3316 case SZOMB: c = 'Z'; break; 3317 case SSTOP: c = 'T'; break; 3318 case SIDL: c = 'I'; break; 3319 case SONPROC: c = 'O'; break; 3320 #ifdef SXBRK 3321 case SXBRK: c = 'X'; break; 3322 #endif 3323 default: c = '?'; break; 3324 } 3325 psp->pr_state = state; 3326 psp->pr_sname = c; 3327 psp->pr_zomb = (state == SZOMB); 3328 /* 3329 * only export SSYS and SMSACCT; everything else is off-limits to 3330 * userland apps. 3331 */ 3332 psp->pr_flag = p->p_flag & (SSYS | SMSACCT); 3333 3334 mutex_enter(&p->p_crlock); 3335 cred = p->p_cred; 3336 psp->pr_uid = crgetruid(cred); 3337 psp->pr_gid = crgetrgid(cred); 3338 psp->pr_euid = crgetuid(cred); 3339 psp->pr_egid = crgetgid(cred); 3340 mutex_exit(&p->p_crlock); 3341 3342 psp->pr_pid = p->p_pid; 3343 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 3344 (p->p_flag & SZONETOP)) { 3345 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 3346 /* 3347 * Inside local zones, fake zsched's pid as parent pids for 3348 * processes which reference processes outside of the zone. 3349 */ 3350 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 3351 } else { 3352 psp->pr_ppid = p->p_ppid; 3353 } 3354 psp->pr_pgrp = p->p_pgrp; 3355 psp->pr_sid = p->p_sessp->s_sid; 3356 psp->pr_addr = prgetpsaddr(p); 3357 hrutime = mstate_aggr_state(p, LMS_USER); 3358 hrstime = mstate_aggr_state(p, LMS_SYSTEM); 3359 hrt2ts(hrutime + hrstime, &psp->pr_time); 3360 TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime); 3361 switch (p->p_model) { 3362 case DATAMODEL_ILP32: 3363 psp->pr_dmodel = PR_MODEL_ILP32; 3364 break; 3365 case DATAMODEL_LP64: 3366 psp->pr_dmodel = PR_MODEL_LP64; 3367 break; 3368 } 3369 if (state == SZOMB || t == NULL) { 3370 int wcode = p->p_wcode; /* must be atomic read */ 3371 3372 if (wcode) 3373 psp->pr_wstat = wstat(wcode, p->p_wdata); 3374 psp->pr_lttydev = PRNODEV; 3375 psp->pr_ottydev = (o_dev_t)PRNODEV; 3376 psp->pr_size = 0; 3377 psp->pr_rssize = 0; 3378 psp->pr_pctmem = 0; 3379 } else { 3380 up = PTOU(p); 3381 psp->pr_wchan = t->t_wchan; 3382 psp->pr_pri = t->t_pri; 3383 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name, 3384 sizeof (psp->pr_clname) - 1); 3385 retval = CL_DONICE(t, NULL, 0, &niceval); 3386 if (retval == 0) { 3387 psp->pr_oldpri = v.v_maxsyspri - psp->pr_pri; 3388 psp->pr_nice = niceval + NZERO; 3389 } else { 3390 psp->pr_oldpri = 0; 3391 psp->pr_nice = 0; 3392 } 3393 d = cttydev(p); 3394 #ifdef sun 3395 { 3396 extern dev_t rwsconsdev, rconsdev, uconsdev; 3397 /* 3398 * If the controlling terminal is the real 3399 * or workstation console device, map to what the 3400 * user thinks is the console device. Handle case when 3401 * rwsconsdev or rconsdev is set to NODEV for Starfire. 3402 */ 3403 if ((d == rwsconsdev || d == rconsdev) && d != NODEV) 3404 d = uconsdev; 3405 } 3406 #endif 3407 psp->pr_lttydev = (d == NODEV) ? PRNODEV : d; 3408 psp->pr_ottydev = cmpdev(d); 3409 psp->pr_start = up->u_start; 3410 bcopy(up->u_comm, psp->pr_fname, 3411 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1)); 3412 bcopy(up->u_psargs, psp->pr_psargs, 3413 MIN(PRARGSZ-1, PSARGSZ)); 3414 psp->pr_syscall = t->t_sysnum; 3415 psp->pr_argc = up->u_argc; 3416 psp->pr_argv = (char **)up->u_argv; 3417 psp->pr_envp = (char **)up->u_envp; 3418 3419 /* compute %cpu for the lwp or process */ 3420 pct = 0; 3421 if ((t = tp) == NULL) 3422 t = p->p_tlist; 3423 cur_time = gethrtime_unscaled(); 3424 do { 3425 pct += cpu_update_pct(t, cur_time); 3426 if (tp != NULL) /* just do the one lwp */ 3427 break; 3428 } while ((t = t->t_forw) != p->p_tlist); 3429 3430 psp->pr_pctcpu = prgetpctcpu(pct); 3431 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */ 3432 if (psp->pr_cpu > 99) 3433 psp->pr_cpu = 99; 3434 3435 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 3436 psp->pr_size = 0; 3437 psp->pr_rssize = 0; 3438 psp->pr_pctmem = 0; 3439 } else { 3440 mutex_exit(&p->p_lock); 3441 AS_LOCK_ENTER(as, RW_READER); 3442 psp->pr_size = btopr(as->a_resvsize); 3443 psp->pr_rssize = rm_asrss(as); 3444 psp->pr_pctmem = rm_pctmemory(as); 3445 AS_LOCK_EXIT(as); 3446 mutex_enter(&p->p_lock); 3447 } 3448 } 3449 psp->pr_bysize = ptob(psp->pr_size); 3450 psp->pr_byrssize = ptob(psp->pr_rssize); 3451 } 3452 3453 /* 3454 * Return an array of structures with memory map information. 3455 * We allocate here; the caller must deallocate. 3456 * The caller is also responsible to append the zero-filled entry 3457 * that terminates the PIOCMAP output buffer. 3458 */ 3459 static int 3460 oprgetmap(proc_t *p, list_t *iolhead) 3461 { 3462 struct as *as = p->p_as; 3463 prmap_t *mp; 3464 struct seg *seg; 3465 struct seg *brkseg, *stkseg; 3466 uint_t prot; 3467 3468 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3469 3470 /* 3471 * Request an initial buffer size that doesn't waste memory 3472 * if the address space has only a small number of segments. 3473 */ 3474 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 3475 3476 if ((seg = AS_SEGFIRST(as)) == NULL) 3477 return (0); 3478 3479 brkseg = break_seg(p); 3480 stkseg = as_segat(as, prgetstackbase(p)); 3481 3482 do { 3483 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3484 caddr_t saddr, naddr; 3485 void *tmp = NULL; 3486 3487 if ((seg->s_flags & S_HOLE) != 0) { 3488 continue; 3489 } 3490 3491 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3492 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3493 if (saddr == naddr) 3494 continue; 3495 3496 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 3497 3498 mp->pr_vaddr = saddr; 3499 mp->pr_size = naddr - saddr; 3500 mp->pr_off = SEGOP_GETOFFSET(seg, saddr); 3501 mp->pr_mflags = 0; 3502 if (prot & PROT_READ) 3503 mp->pr_mflags |= MA_READ; 3504 if (prot & PROT_WRITE) 3505 mp->pr_mflags |= MA_WRITE; 3506 if (prot & PROT_EXEC) 3507 mp->pr_mflags |= MA_EXEC; 3508 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3509 mp->pr_mflags |= MA_SHARED; 3510 if (seg == brkseg) 3511 mp->pr_mflags |= MA_BREAK; 3512 else if (seg == stkseg) 3513 mp->pr_mflags |= MA_STACK; 3514 mp->pr_pagesize = PAGESIZE; 3515 } 3516 ASSERT(tmp == NULL); 3517 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3518 3519 return (0); 3520 } 3521 3522 #ifdef _SYSCALL32_IMPL 3523 static int 3524 oprgetmap32(proc_t *p, list_t *iolhead) 3525 { 3526 struct as *as = p->p_as; 3527 ioc_prmap32_t *mp; 3528 struct seg *seg; 3529 struct seg *brkseg, *stkseg; 3530 uint_t prot; 3531 3532 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3533 3534 /* 3535 * Request an initial buffer size that doesn't waste memory 3536 * if the address space has only a small number of segments. 3537 */ 3538 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 3539 3540 if ((seg = AS_SEGFIRST(as)) == NULL) 3541 return (0); 3542 3543 brkseg = break_seg(p); 3544 stkseg = as_segat(as, prgetstackbase(p)); 3545 3546 do { 3547 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3548 caddr_t saddr, naddr; 3549 void *tmp = NULL; 3550 3551 if ((seg->s_flags & S_HOLE) != 0) { 3552 continue; 3553 } 3554 3555 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3556 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3557 if (saddr == naddr) 3558 continue; 3559 3560 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 3561 3562 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr; 3563 mp->pr_size = (size32_t)(naddr - saddr); 3564 mp->pr_off = (off32_t)SEGOP_GETOFFSET(seg, saddr); 3565 mp->pr_mflags = 0; 3566 if (prot & PROT_READ) 3567 mp->pr_mflags |= MA_READ; 3568 if (prot & PROT_WRITE) 3569 mp->pr_mflags |= MA_WRITE; 3570 if (prot & PROT_EXEC) 3571 mp->pr_mflags |= MA_EXEC; 3572 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3573 mp->pr_mflags |= MA_SHARED; 3574 if (seg == brkseg) 3575 mp->pr_mflags |= MA_BREAK; 3576 else if (seg == stkseg) 3577 mp->pr_mflags |= MA_STACK; 3578 mp->pr_pagesize = PAGESIZE; 3579 } 3580 ASSERT(tmp == NULL); 3581 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3582 3583 return (0); 3584 } 3585 #endif /* _SYSCALL32_IMPL */ 3586 3587 /* 3588 * Return the size of the old /proc page data file. 3589 */ 3590 size_t 3591 oprpdsize(struct as *as) 3592 { 3593 struct seg *seg; 3594 size_t size; 3595 3596 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3597 3598 if ((seg = AS_SEGFIRST(as)) == NULL) 3599 return (0); 3600 3601 size = sizeof (prpageheader_t); 3602 do { 3603 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3604 caddr_t saddr, naddr; 3605 void *tmp = NULL; 3606 size_t npage; 3607 3608 if ((seg->s_flags & S_HOLE) != 0) { 3609 continue; 3610 } 3611 3612 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3613 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3614 if ((npage = (naddr - saddr) / PAGESIZE) != 0) 3615 size += sizeof (prasmap_t) + roundlong(npage); 3616 } 3617 ASSERT(tmp == NULL); 3618 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3619 3620 return (size); 3621 } 3622 3623 #ifdef _SYSCALL32_IMPL 3624 size_t 3625 oprpdsize32(struct as *as) 3626 { 3627 struct seg *seg; 3628 size_t size; 3629 3630 ASSERT(as != &kas && AS_WRITE_HELD(as)); 3631 3632 if ((seg = AS_SEGFIRST(as)) == NULL) 3633 return (0); 3634 3635 size = sizeof (ioc_prpageheader32_t); 3636 do { 3637 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3638 caddr_t saddr, naddr; 3639 void *tmp = NULL; 3640 size_t npage; 3641 3642 if ((seg->s_flags & S_HOLE) != 0) { 3643 continue; 3644 } 3645 3646 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3647 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3648 if ((npage = (naddr - saddr) / PAGESIZE) != 0) 3649 size += sizeof (ioc_prmap32_t) + round4(npage); 3650 } 3651 ASSERT(tmp == NULL); 3652 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3653 3654 return (size); 3655 } 3656 #endif /* _SYSCALL32_IMPL */ 3657 3658 /* 3659 * Read old /proc page data information. 3660 */ 3661 int 3662 oprpdread(struct as *as, uint_t hatid, struct uio *uiop) 3663 { 3664 caddr_t buf; 3665 size_t size; 3666 prpageheader_t *php; 3667 prasmap_t *pmp; 3668 struct seg *seg; 3669 int error; 3670 3671 again: 3672 AS_LOCK_ENTER(as, RW_WRITER); 3673 3674 if ((seg = AS_SEGFIRST(as)) == NULL) { 3675 AS_LOCK_EXIT(as); 3676 return (0); 3677 } 3678 size = oprpdsize(as); 3679 if (uiop->uio_resid < size) { 3680 AS_LOCK_EXIT(as); 3681 return (E2BIG); 3682 } 3683 3684 buf = kmem_zalloc(size, KM_SLEEP); 3685 php = (prpageheader_t *)buf; 3686 pmp = (prasmap_t *)(buf + sizeof (prpageheader_t)); 3687 3688 hrt2ts(gethrtime(), &php->pr_tstamp); 3689 php->pr_nmap = 0; 3690 php->pr_npage = 0; 3691 do { 3692 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3693 caddr_t saddr, naddr; 3694 void *tmp = NULL; 3695 3696 if ((seg->s_flags & S_HOLE) != 0) { 3697 continue; 3698 } 3699 3700 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3701 size_t len; 3702 size_t npage; 3703 uint_t prot; 3704 uintptr_t next; 3705 3706 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3707 if ((len = naddr - saddr) == 0) 3708 continue; 3709 npage = len / PAGESIZE; 3710 next = (uintptr_t)(pmp + 1) + roundlong(npage); 3711 /* 3712 * It's possible that the address space can change 3713 * subtlely even though we're holding as->a_lock 3714 * due to the nondeterminism of page_exists() in 3715 * the presence of asychronously flushed pages or 3716 * mapped files whose sizes are changing. 3717 * page_exists() may be called indirectly from 3718 * pr_getprot() by a SEGOP_INCORE() routine. 3719 * If this happens we need to make sure we don't 3720 * overrun the buffer whose size we computed based 3721 * on the initial iteration through the segments. 3722 * Once we've detected an overflow, we need to clean 3723 * up the temporary memory allocated in pr_getprot() 3724 * and retry. If there's a pending signal, we return 3725 * EINTR so that this thread can be dislodged if 3726 * a latent bug causes us to spin indefinitely. 3727 */ 3728 if (next > (uintptr_t)buf + size) { 3729 pr_getprot_done(&tmp); 3730 AS_LOCK_EXIT(as); 3731 3732 kmem_free(buf, size); 3733 3734 if (ISSIG(curthread, JUSTLOOKING)) 3735 return (EINTR); 3736 3737 goto again; 3738 } 3739 3740 php->pr_nmap++; 3741 php->pr_npage += npage; 3742 pmp->pr_vaddr = saddr; 3743 pmp->pr_npage = npage; 3744 pmp->pr_off = SEGOP_GETOFFSET(seg, saddr); 3745 pmp->pr_mflags = 0; 3746 if (prot & PROT_READ) 3747 pmp->pr_mflags |= MA_READ; 3748 if (prot & PROT_WRITE) 3749 pmp->pr_mflags |= MA_WRITE; 3750 if (prot & PROT_EXEC) 3751 pmp->pr_mflags |= MA_EXEC; 3752 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3753 pmp->pr_mflags |= MA_SHARED; 3754 pmp->pr_pagesize = PAGESIZE; 3755 hat_getstat(as, saddr, len, hatid, 3756 (char *)(pmp + 1), HAT_SYNC_ZERORM); 3757 pmp = (prasmap_t *)next; 3758 } 3759 ASSERT(tmp == NULL); 3760 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3761 3762 AS_LOCK_EXIT(as); 3763 3764 ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size); 3765 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop); 3766 kmem_free(buf, size); 3767 3768 return (error); 3769 } 3770 3771 #ifdef _SYSCALL32_IMPL 3772 int 3773 oprpdread32(struct as *as, uint_t hatid, struct uio *uiop) 3774 { 3775 caddr_t buf; 3776 size_t size; 3777 ioc_prpageheader32_t *php; 3778 ioc_prasmap32_t *pmp; 3779 struct seg *seg; 3780 int error; 3781 3782 again: 3783 AS_LOCK_ENTER(as, RW_WRITER); 3784 3785 if ((seg = AS_SEGFIRST(as)) == NULL) { 3786 AS_LOCK_EXIT(as); 3787 return (0); 3788 } 3789 size = oprpdsize32(as); 3790 if (uiop->uio_resid < size) { 3791 AS_LOCK_EXIT(as); 3792 return (E2BIG); 3793 } 3794 3795 buf = kmem_zalloc(size, KM_SLEEP); 3796 php = (ioc_prpageheader32_t *)buf; 3797 pmp = (ioc_prasmap32_t *)(buf + sizeof (ioc_prpageheader32_t)); 3798 3799 hrt2ts32(gethrtime(), &php->pr_tstamp); 3800 php->pr_nmap = 0; 3801 php->pr_npage = 0; 3802 do { 3803 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 3804 caddr_t saddr, naddr; 3805 void *tmp = NULL; 3806 3807 if ((seg->s_flags & S_HOLE) != 0) { 3808 continue; 3809 } 3810 3811 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 3812 size_t len; 3813 size_t npage; 3814 uint_t prot; 3815 uintptr_t next; 3816 3817 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 3818 if ((len = naddr - saddr) == 0) 3819 continue; 3820 npage = len / PAGESIZE; 3821 next = (uintptr_t)(pmp + 1) + round4(npage); 3822 /* 3823 * It's possible that the address space can change 3824 * subtlely even though we're holding as->a_lock 3825 * due to the nondeterminism of page_exists() in 3826 * the presence of asychronously flushed pages or 3827 * mapped files whose sizes are changing. 3828 * page_exists() may be called indirectly from 3829 * pr_getprot() by a SEGOP_INCORE() routine. 3830 * If this happens we need to make sure we don't 3831 * overrun the buffer whose size we computed based 3832 * on the initial iteration through the segments. 3833 * Once we've detected an overflow, we need to clean 3834 * up the temporary memory allocated in pr_getprot() 3835 * and retry. If there's a pending signal, we return 3836 * EINTR so that this thread can be dislodged if 3837 * a latent bug causes us to spin indefinitely. 3838 */ 3839 if (next > (uintptr_t)buf + size) { 3840 pr_getprot_done(&tmp); 3841 AS_LOCK_EXIT(as); 3842 3843 kmem_free(buf, size); 3844 3845 if (ISSIG(curthread, JUSTLOOKING)) 3846 return (EINTR); 3847 3848 goto again; 3849 } 3850 3851 php->pr_nmap++; 3852 php->pr_npage += npage; 3853 pmp->pr_vaddr = (uint32_t)(uintptr_t)saddr; 3854 pmp->pr_npage = (uint32_t)npage; 3855 pmp->pr_off = (int32_t)SEGOP_GETOFFSET(seg, saddr); 3856 pmp->pr_mflags = 0; 3857 if (prot & PROT_READ) 3858 pmp->pr_mflags |= MA_READ; 3859 if (prot & PROT_WRITE) 3860 pmp->pr_mflags |= MA_WRITE; 3861 if (prot & PROT_EXEC) 3862 pmp->pr_mflags |= MA_EXEC; 3863 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 3864 pmp->pr_mflags |= MA_SHARED; 3865 pmp->pr_pagesize = PAGESIZE; 3866 hat_getstat(as, saddr, len, hatid, 3867 (char *)(pmp + 1), HAT_SYNC_ZERORM); 3868 pmp = (ioc_prasmap32_t *)next; 3869 } 3870 ASSERT(tmp == NULL); 3871 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 3872 3873 AS_LOCK_EXIT(as); 3874 3875 ASSERT((uintptr_t)pmp == (uintptr_t)buf + size); 3876 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop); 3877 kmem_free(buf, size); 3878 3879 return (error); 3880 } 3881 #endif /* _SYSCALL32_IMPL */ 3882 3883 /*ARGSUSED*/ 3884 #ifdef _SYSCALL32_IMPL 3885 int 3886 prioctl( 3887 struct vnode *vp, 3888 int cmd, 3889 intptr_t arg, 3890 int flag, 3891 cred_t *cr, 3892 int *rvalp, 3893 caller_context_t *ct) 3894 { 3895 switch (curproc->p_model) { 3896 case DATAMODEL_ILP32: 3897 return (prioctl32(vp, cmd, arg, flag, cr, rvalp, ct)); 3898 case DATAMODEL_LP64: 3899 return (prioctl64(vp, cmd, arg, flag, cr, rvalp, ct)); 3900 default: 3901 return (ENOSYS); 3902 } 3903 } 3904 #endif /* _SYSCALL32_IMPL */ 3905