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