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