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