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