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