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