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