1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2013, Joyent, Inc. All rights reserved. 25 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 26 */ 27 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 31 #include <sys/types.h> 32 #include <sys/t_lock.h> 33 #include <sys/param.h> 34 #include <sys/cmn_err.h> 35 #include <sys/cred.h> 36 #include <sys/priv.h> 37 #include <sys/debug.h> 38 #include <sys/errno.h> 39 #include <sys/inline.h> 40 #include <sys/kmem.h> 41 #include <sys/mman.h> 42 #include <sys/proc.h> 43 #include <sys/brand.h> 44 #include <sys/sobject.h> 45 #include <sys/sysmacros.h> 46 #include <sys/systm.h> 47 #include <sys/uio.h> 48 #include <sys/var.h> 49 #include <sys/vfs.h> 50 #include <sys/vnode.h> 51 #include <sys/session.h> 52 #include <sys/pcb.h> 53 #include <sys/signal.h> 54 #include <sys/user.h> 55 #include <sys/disp.h> 56 #include <sys/class.h> 57 #include <sys/ts.h> 58 #include <sys/bitmap.h> 59 #include <sys/poll.h> 60 #include <sys/shm_impl.h> 61 #include <sys/fault.h> 62 #include <sys/syscall.h> 63 #include <sys/procfs.h> 64 #include <sys/processor.h> 65 #include <sys/cpuvar.h> 66 #include <sys/copyops.h> 67 #include <sys/time.h> 68 #include <sys/msacct.h> 69 #include <sys/flock_impl.h> 70 #include <sys/stropts.h> 71 #include <sys/strsubr.h> 72 #include <sys/pathname.h> 73 #include <sys/mode.h> 74 #include <sys/socketvar.h> 75 #include <sys/autoconf.h> 76 #include <sys/dtrace.h> 77 #include <sys/timod.h> 78 #include <netinet/udp.h> 79 #include <netinet/tcp.h> 80 #include <inet/cc.h> 81 #include <vm/as.h> 82 #include <vm/rm.h> 83 #include <vm/seg.h> 84 #include <vm/seg_vn.h> 85 #include <vm/seg_dev.h> 86 #include <vm/seg_spt.h> 87 #include <vm/page.h> 88 #include <sys/vmparam.h> 89 #include <sys/swap.h> 90 #include <fs/proc/prdata.h> 91 #include <sys/task.h> 92 #include <sys/project.h> 93 #include <sys/contract_impl.h> 94 #include <sys/contract/process.h> 95 #include <sys/contract/process_impl.h> 96 #include <sys/schedctl.h> 97 #include <sys/pool.h> 98 #include <sys/zone.h> 99 #include <sys/atomic.h> 100 #include <sys/sdt.h> 101 102 #define MAX_ITERS_SPIN 5 103 104 typedef struct prpagev { 105 uint_t *pg_protv; /* vector of page permissions */ 106 char *pg_incore; /* vector of incore flags */ 107 size_t pg_npages; /* number of pages in protv and incore */ 108 ulong_t pg_pnbase; /* pn within segment of first protv element */ 109 } prpagev_t; 110 111 size_t pagev_lim = 256 * 1024; /* limit on number of pages in prpagev_t */ 112 113 extern struct seg_ops segdev_ops; /* needs a header file */ 114 extern struct seg_ops segspt_shmops; /* needs a header file */ 115 116 static int set_watched_page(proc_t *, caddr_t, caddr_t, ulong_t, ulong_t); 117 static void clear_watched_page(proc_t *, caddr_t, caddr_t, ulong_t); 118 119 /* 120 * Choose an lwp from the complete set of lwps for the process. 121 * This is called for any operation applied to the process 122 * file descriptor that requires an lwp to operate upon. 123 * 124 * Returns a pointer to the thread for the selected LWP, 125 * and with the dispatcher lock held for the thread. 126 * 127 * The algorithm for choosing an lwp is critical for /proc semantics; 128 * don't touch this code unless you know all of the implications. 129 */ 130 kthread_t * 131 prchoose(proc_t *p) 132 { 133 kthread_t *t; 134 kthread_t *t_onproc = NULL; /* running on processor */ 135 kthread_t *t_run = NULL; /* runnable, on disp queue */ 136 kthread_t *t_sleep = NULL; /* sleeping */ 137 kthread_t *t_hold = NULL; /* sleeping, performing hold */ 138 kthread_t *t_susp = NULL; /* suspended stop */ 139 kthread_t *t_jstop = NULL; /* jobcontrol stop, w/o directed stop */ 140 kthread_t *t_jdstop = NULL; /* jobcontrol stop with directed stop */ 141 kthread_t *t_req = NULL; /* requested stop */ 142 kthread_t *t_istop = NULL; /* event-of-interest stop */ 143 kthread_t *t_dtrace = NULL; /* DTrace stop */ 144 145 ASSERT(MUTEX_HELD(&p->p_lock)); 146 147 /* 148 * If the agent lwp exists, it takes precedence over all others. 149 */ 150 if ((t = p->p_agenttp) != NULL) { 151 thread_lock(t); 152 return (t); 153 } 154 155 if ((t = p->p_tlist) == NULL) /* start at the head of the list */ 156 return (t); 157 do { /* for eacn lwp in the process */ 158 if (VSTOPPED(t)) { /* virtually stopped */ 159 if (t_req == NULL) 160 t_req = t; 161 continue; 162 } 163 164 thread_lock(t); /* make sure thread is in good state */ 165 switch (t->t_state) { 166 default: 167 panic("prchoose: bad thread state %d, thread 0x%p", 168 t->t_state, (void *)t); 169 /*NOTREACHED*/ 170 case TS_SLEEP: 171 /* this is filthy */ 172 if (t->t_wchan == (caddr_t)&p->p_holdlwps && 173 t->t_wchan0 == NULL) { 174 if (t_hold == NULL) 175 t_hold = t; 176 } else { 177 if (t_sleep == NULL) 178 t_sleep = t; 179 } 180 break; 181 case TS_RUN: 182 case TS_WAIT: 183 if (t_run == NULL) 184 t_run = t; 185 break; 186 case TS_ONPROC: 187 if (t_onproc == NULL) 188 t_onproc = t; 189 break; 190 case TS_ZOMB: /* last possible choice */ 191 break; 192 case TS_STOPPED: 193 switch (t->t_whystop) { 194 case PR_SUSPENDED: 195 if (t_susp == NULL) 196 t_susp = t; 197 break; 198 case PR_JOBCONTROL: 199 if (t->t_proc_flag & TP_PRSTOP) { 200 if (t_jdstop == NULL) 201 t_jdstop = t; 202 } else { 203 if (t_jstop == NULL) 204 t_jstop = t; 205 } 206 break; 207 case PR_REQUESTED: 208 if (t->t_dtrace_stop && t_dtrace == NULL) 209 t_dtrace = t; 210 else if (t_req == NULL) 211 t_req = t; 212 break; 213 case PR_SYSENTRY: 214 case PR_SYSEXIT: 215 case PR_SIGNALLED: 216 case PR_FAULTED: 217 /* 218 * Make an lwp calling exit() be the 219 * last lwp seen in the process. 220 */ 221 if (t_istop == NULL || 222 (t_istop->t_whystop == PR_SYSENTRY && 223 t_istop->t_whatstop == SYS_exit)) 224 t_istop = t; 225 break; 226 case PR_CHECKPOINT: /* can't happen? */ 227 break; 228 default: 229 panic("prchoose: bad t_whystop %d, thread 0x%p", 230 t->t_whystop, (void *)t); 231 /*NOTREACHED*/ 232 } 233 break; 234 } 235 thread_unlock(t); 236 } while ((t = t->t_forw) != p->p_tlist); 237 238 if (t_onproc) 239 t = t_onproc; 240 else if (t_run) 241 t = t_run; 242 else if (t_sleep) 243 t = t_sleep; 244 else if (t_jstop) 245 t = t_jstop; 246 else if (t_jdstop) 247 t = t_jdstop; 248 else if (t_istop) 249 t = t_istop; 250 else if (t_dtrace) 251 t = t_dtrace; 252 else if (t_req) 253 t = t_req; 254 else if (t_hold) 255 t = t_hold; 256 else if (t_susp) 257 t = t_susp; 258 else /* TS_ZOMB */ 259 t = p->p_tlist; 260 261 if (t != NULL) 262 thread_lock(t); 263 return (t); 264 } 265 266 /* 267 * Wakeup anyone sleeping on the /proc vnode for the process/lwp to stop. 268 * Also call pollwakeup() if any lwps are waiting in poll() for POLLPRI 269 * on the /proc file descriptor. Called from stop() when a traced 270 * process stops on an event of interest. Also called from exit() 271 * and prinvalidate() to indicate POLLHUP and POLLERR respectively. 272 */ 273 void 274 prnotify(struct vnode *vp) 275 { 276 prcommon_t *pcp = VTOP(vp)->pr_common; 277 278 mutex_enter(&pcp->prc_mutex); 279 cv_broadcast(&pcp->prc_wait); 280 mutex_exit(&pcp->prc_mutex); 281 if (pcp->prc_flags & PRC_POLL) { 282 /* 283 * We call pollwakeup() with POLLHUP to ensure that 284 * the pollers are awakened even if they are polling 285 * for nothing (i.e., waiting for the process to exit). 286 * This enables the use of the PRC_POLL flag for optimization 287 * (we can turn off PRC_POLL only if we know no pollers remain). 288 */ 289 pcp->prc_flags &= ~PRC_POLL; 290 pollwakeup(&pcp->prc_pollhead, POLLHUP); 291 } 292 } 293 294 /* called immediately below, in prfree() */ 295 static void 296 prfreenotify(vnode_t *vp) 297 { 298 prnode_t *pnp; 299 prcommon_t *pcp; 300 301 while (vp != NULL) { 302 pnp = VTOP(vp); 303 pcp = pnp->pr_common; 304 ASSERT(pcp->prc_thread == NULL); 305 pcp->prc_proc = NULL; 306 /* 307 * We can't call prnotify() here because we are holding 308 * pidlock. We assert that there is no need to. 309 */ 310 mutex_enter(&pcp->prc_mutex); 311 cv_broadcast(&pcp->prc_wait); 312 mutex_exit(&pcp->prc_mutex); 313 ASSERT(!(pcp->prc_flags & PRC_POLL)); 314 315 vp = pnp->pr_next; 316 pnp->pr_next = NULL; 317 } 318 } 319 320 /* 321 * Called from a hook in freeproc() when a traced process is removed 322 * from the process table. The proc-table pointers of all associated 323 * /proc vnodes are cleared to indicate that the process has gone away. 324 */ 325 void 326 prfree(proc_t *p) 327 { 328 uint_t slot = p->p_slot; 329 330 ASSERT(MUTEX_HELD(&pidlock)); 331 332 /* 333 * Block the process against /proc so it can be freed. 334 * It cannot be freed while locked by some controlling process. 335 * Lock ordering: 336 * pidlock -> pr_pidlock -> p->p_lock -> pcp->prc_mutex 337 */ 338 mutex_enter(&pr_pidlock); /* protects pcp->prc_proc */ 339 mutex_enter(&p->p_lock); 340 while (p->p_proc_flag & P_PR_LOCK) { 341 mutex_exit(&pr_pidlock); 342 cv_wait(&pr_pid_cv[slot], &p->p_lock); 343 mutex_exit(&p->p_lock); 344 mutex_enter(&pr_pidlock); 345 mutex_enter(&p->p_lock); 346 } 347 348 ASSERT(p->p_tlist == NULL); 349 350 prfreenotify(p->p_plist); 351 p->p_plist = NULL; 352 353 prfreenotify(p->p_trace); 354 p->p_trace = NULL; 355 356 /* 357 * We broadcast to wake up everyone waiting for this process. 358 * No one can reach this process from this point on. 359 */ 360 cv_broadcast(&pr_pid_cv[slot]); 361 362 mutex_exit(&p->p_lock); 363 mutex_exit(&pr_pidlock); 364 } 365 366 /* 367 * Called from a hook in exit() when a traced process is becoming a zombie. 368 */ 369 void 370 prexit(proc_t *p) 371 { 372 ASSERT(MUTEX_HELD(&p->p_lock)); 373 374 if (pr_watch_active(p)) { 375 pr_free_watchpoints(p); 376 watch_disable(curthread); 377 } 378 /* pr_free_watched_pages() is called in exit(), after dropping p_lock */ 379 if (p->p_trace) { 380 VTOP(p->p_trace)->pr_common->prc_flags |= PRC_DESTROY; 381 prnotify(p->p_trace); 382 } 383 cv_broadcast(&pr_pid_cv[p->p_slot]); /* pauselwps() */ 384 } 385 386 /* 387 * Called when a thread calls lwp_exit(). 388 */ 389 void 390 prlwpexit(kthread_t *t) 391 { 392 vnode_t *vp; 393 prnode_t *pnp; 394 prcommon_t *pcp; 395 proc_t *p = ttoproc(t); 396 lwpent_t *lep = p->p_lwpdir[t->t_dslot].ld_entry; 397 398 ASSERT(t == curthread); 399 ASSERT(MUTEX_HELD(&p->p_lock)); 400 401 /* 402 * The process must be blocked against /proc to do this safely. 403 * The lwp must not disappear while the process is marked P_PR_LOCK. 404 * It is the caller's responsibility to have called prbarrier(p). 405 */ 406 ASSERT(!(p->p_proc_flag & P_PR_LOCK)); 407 408 for (vp = p->p_plist; vp != NULL; vp = pnp->pr_next) { 409 pnp = VTOP(vp); 410 pcp = pnp->pr_common; 411 if (pcp->prc_thread == t) { 412 pcp->prc_thread = NULL; 413 pcp->prc_flags |= PRC_DESTROY; 414 } 415 } 416 417 for (vp = lep->le_trace; vp != NULL; vp = pnp->pr_next) { 418 pnp = VTOP(vp); 419 pcp = pnp->pr_common; 420 pcp->prc_thread = NULL; 421 pcp->prc_flags |= PRC_DESTROY; 422 prnotify(vp); 423 } 424 425 if (p->p_trace) 426 prnotify(p->p_trace); 427 } 428 429 /* 430 * Called when a zombie thread is joined or when a 431 * detached lwp exits. Called from lwp_hash_out(). 432 */ 433 void 434 prlwpfree(proc_t *p, lwpent_t *lep) 435 { 436 vnode_t *vp; 437 prnode_t *pnp; 438 prcommon_t *pcp; 439 440 ASSERT(MUTEX_HELD(&p->p_lock)); 441 442 /* 443 * The process must be blocked against /proc to do this safely. 444 * The lwp must not disappear while the process is marked P_PR_LOCK. 445 * It is the caller's responsibility to have called prbarrier(p). 446 */ 447 ASSERT(!(p->p_proc_flag & P_PR_LOCK)); 448 449 vp = lep->le_trace; 450 lep->le_trace = NULL; 451 while (vp) { 452 prnotify(vp); 453 pnp = VTOP(vp); 454 pcp = pnp->pr_common; 455 ASSERT(pcp->prc_thread == NULL && 456 (pcp->prc_flags & PRC_DESTROY)); 457 pcp->prc_tslot = -1; 458 vp = pnp->pr_next; 459 pnp->pr_next = NULL; 460 } 461 462 if (p->p_trace) 463 prnotify(p->p_trace); 464 } 465 466 /* 467 * Called from a hook in exec() when a thread starts exec(). 468 */ 469 void 470 prexecstart(void) 471 { 472 proc_t *p = ttoproc(curthread); 473 klwp_t *lwp = ttolwp(curthread); 474 475 /* 476 * The P_PR_EXEC flag blocks /proc operations for 477 * the duration of the exec(). 478 * We can't start exec() while the process is 479 * locked by /proc, so we call prbarrier(). 480 * lwp_nostop keeps the process from being stopped 481 * via job control for the duration of the exec(). 482 */ 483 484 ASSERT(MUTEX_HELD(&p->p_lock)); 485 prbarrier(p); 486 lwp->lwp_nostop++; 487 p->p_proc_flag |= P_PR_EXEC; 488 } 489 490 /* 491 * Called from a hook in exec() when a thread finishes exec(). 492 * The thread may or may not have succeeded. Some other thread 493 * may have beat it to the punch. 494 */ 495 void 496 prexecend(void) 497 { 498 proc_t *p = ttoproc(curthread); 499 klwp_t *lwp = ttolwp(curthread); 500 vnode_t *vp; 501 prnode_t *pnp; 502 prcommon_t *pcp; 503 model_t model = p->p_model; 504 id_t tid = curthread->t_tid; 505 int tslot = curthread->t_dslot; 506 507 ASSERT(MUTEX_HELD(&p->p_lock)); 508 509 lwp->lwp_nostop--; 510 if (p->p_flag & SEXITLWPS) { 511 /* 512 * We are on our way to exiting because some 513 * other thread beat us in the race to exec(). 514 * Don't clear the P_PR_EXEC flag in this case. 515 */ 516 return; 517 } 518 519 /* 520 * Wake up anyone waiting in /proc for the process to complete exec(). 521 */ 522 p->p_proc_flag &= ~P_PR_EXEC; 523 if ((vp = p->p_trace) != NULL) { 524 pcp = VTOP(vp)->pr_common; 525 mutex_enter(&pcp->prc_mutex); 526 cv_broadcast(&pcp->prc_wait); 527 mutex_exit(&pcp->prc_mutex); 528 for (; vp != NULL; vp = pnp->pr_next) { 529 pnp = VTOP(vp); 530 pnp->pr_common->prc_datamodel = model; 531 } 532 } 533 if ((vp = p->p_lwpdir[tslot].ld_entry->le_trace) != NULL) { 534 /* 535 * We dealt with the process common above. 536 */ 537 ASSERT(p->p_trace != NULL); 538 pcp = VTOP(vp)->pr_common; 539 mutex_enter(&pcp->prc_mutex); 540 cv_broadcast(&pcp->prc_wait); 541 mutex_exit(&pcp->prc_mutex); 542 for (; vp != NULL; vp = pnp->pr_next) { 543 pnp = VTOP(vp); 544 pcp = pnp->pr_common; 545 pcp->prc_datamodel = model; 546 pcp->prc_tid = tid; 547 pcp->prc_tslot = tslot; 548 } 549 } 550 } 551 552 /* 553 * Called from a hook in relvm() just before freeing the address space. 554 * We free all the watched areas now. 555 */ 556 void 557 prrelvm(void) 558 { 559 proc_t *p = ttoproc(curthread); 560 561 mutex_enter(&p->p_lock); 562 prbarrier(p); /* block all other /proc operations */ 563 if (pr_watch_active(p)) { 564 pr_free_watchpoints(p); 565 watch_disable(curthread); 566 } 567 mutex_exit(&p->p_lock); 568 pr_free_watched_pages(p); 569 } 570 571 /* 572 * Called from hooks in exec-related code when a traced process 573 * attempts to exec(2) a setuid/setgid program or an unreadable 574 * file. Rather than fail the exec we invalidate the associated 575 * /proc vnodes so that subsequent attempts to use them will fail. 576 * 577 * All /proc vnodes, except directory vnodes, are retained on a linked 578 * list (rooted at p_plist in the process structure) until last close. 579 * 580 * A controlling process must re-open the /proc files in order to 581 * regain control. 582 */ 583 void 584 prinvalidate(struct user *up) 585 { 586 kthread_t *t = curthread; 587 proc_t *p = ttoproc(t); 588 vnode_t *vp; 589 prnode_t *pnp; 590 int writers = 0; 591 592 mutex_enter(&p->p_lock); 593 prbarrier(p); /* block all other /proc operations */ 594 595 /* 596 * At this moment, there can be only one lwp in the process. 597 */ 598 ASSERT(p->p_lwpcnt == 1 && p->p_zombcnt == 0); 599 600 /* 601 * Invalidate any currently active /proc vnodes. 602 */ 603 for (vp = p->p_plist; vp != NULL; vp = pnp->pr_next) { 604 pnp = VTOP(vp); 605 switch (pnp->pr_type) { 606 case PR_PSINFO: /* these files can read by anyone */ 607 case PR_LPSINFO: 608 case PR_LWPSINFO: 609 case PR_LWPDIR: 610 case PR_LWPIDDIR: 611 case PR_USAGE: 612 case PR_LUSAGE: 613 case PR_LWPUSAGE: 614 break; 615 default: 616 pnp->pr_flags |= PR_INVAL; 617 break; 618 } 619 } 620 /* 621 * Wake up anyone waiting for the process or lwp. 622 * p->p_trace is guaranteed to be non-NULL if there 623 * are any open /proc files for this process. 624 */ 625 if ((vp = p->p_trace) != NULL) { 626 prcommon_t *pcp = VTOP(vp)->pr_pcommon; 627 628 prnotify(vp); 629 /* 630 * Are there any writers? 631 */ 632 if ((writers = pcp->prc_writers) != 0) { 633 /* 634 * Clear the exclusive open flag (old /proc interface). 635 * Set prc_selfopens equal to prc_writers so that 636 * the next O_EXCL|O_WRITE open will succeed 637 * even with existing (though invalid) writers. 638 * prclose() must decrement prc_selfopens when 639 * the invalid files are closed. 640 */ 641 pcp->prc_flags &= ~PRC_EXCL; 642 ASSERT(pcp->prc_selfopens <= writers); 643 pcp->prc_selfopens = writers; 644 } 645 } 646 vp = p->p_lwpdir[t->t_dslot].ld_entry->le_trace; 647 while (vp != NULL) { 648 /* 649 * We should not invalidate the lwpiddir vnodes, 650 * but the necessities of maintaining the old 651 * ioctl()-based version of /proc require it. 652 */ 653 pnp = VTOP(vp); 654 pnp->pr_flags |= PR_INVAL; 655 prnotify(vp); 656 vp = pnp->pr_next; 657 } 658 659 /* 660 * If any tracing flags are in effect and any vnodes are open for 661 * writing then set the requested-stop and run-on-last-close flags. 662 * Otherwise, clear all tracing flags. 663 */ 664 t->t_proc_flag &= ~TP_PAUSE; 665 if ((p->p_proc_flag & P_PR_TRACE) && writers) { 666 t->t_proc_flag |= TP_PRSTOP; 667 aston(t); /* so ISSIG will see the flag */ 668 p->p_proc_flag |= P_PR_RUNLCL; 669 } else { 670 premptyset(&up->u_entrymask); /* syscalls */ 671 premptyset(&up->u_exitmask); 672 up->u_systrap = 0; 673 premptyset(&p->p_sigmask); /* signals */ 674 premptyset(&p->p_fltmask); /* faults */ 675 t->t_proc_flag &= ~(TP_PRSTOP|TP_PRVSTOP|TP_STOPPING); 676 p->p_proc_flag &= ~(P_PR_RUNLCL|P_PR_KILLCL|P_PR_TRACE); 677 prnostep(ttolwp(t)); 678 } 679 680 mutex_exit(&p->p_lock); 681 } 682 683 /* 684 * Acquire the controlled process's p_lock and mark it P_PR_LOCK. 685 * Return with pr_pidlock held in all cases. 686 * Return with p_lock held if the the process still exists. 687 * Return value is the process pointer if the process still exists, else NULL. 688 * If we lock the process, give ourself kernel priority to avoid deadlocks; 689 * this is undone in prunlock(). 690 */ 691 proc_t * 692 pr_p_lock(prnode_t *pnp) 693 { 694 proc_t *p; 695 prcommon_t *pcp; 696 697 mutex_enter(&pr_pidlock); 698 if ((pcp = pnp->pr_pcommon) == NULL || (p = pcp->prc_proc) == NULL) 699 return (NULL); 700 mutex_enter(&p->p_lock); 701 while (p->p_proc_flag & P_PR_LOCK) { 702 /* 703 * This cv/mutex pair is persistent even if 704 * the process disappears while we sleep. 705 */ 706 kcondvar_t *cv = &pr_pid_cv[p->p_slot]; 707 kmutex_t *mp = &p->p_lock; 708 709 mutex_exit(&pr_pidlock); 710 cv_wait(cv, mp); 711 mutex_exit(mp); 712 mutex_enter(&pr_pidlock); 713 if (pcp->prc_proc == NULL) 714 return (NULL); 715 ASSERT(p == pcp->prc_proc); 716 mutex_enter(&p->p_lock); 717 } 718 p->p_proc_flag |= P_PR_LOCK; 719 THREAD_KPRI_REQUEST(); 720 return (p); 721 } 722 723 /* 724 * Lock the target process by setting P_PR_LOCK and grabbing p->p_lock. 725 * This prevents any lwp of the process from disappearing and 726 * blocks most operations that a process can perform on itself. 727 * Returns 0 on success, a non-zero error number on failure. 728 * 729 * 'zdisp' is ZYES or ZNO to indicate whether prlock() should succeed when 730 * the subject process is a zombie (ZYES) or fail for zombies (ZNO). 731 * 732 * error returns: 733 * ENOENT: process or lwp has disappeared or process is exiting 734 * (or has become a zombie and zdisp == ZNO). 735 * EAGAIN: procfs vnode has become invalid. 736 * EINTR: signal arrived while waiting for exec to complete. 737 */ 738 int 739 prlock(prnode_t *pnp, int zdisp) 740 { 741 prcommon_t *pcp; 742 proc_t *p; 743 744 again: 745 pcp = pnp->pr_common; 746 p = pr_p_lock(pnp); 747 mutex_exit(&pr_pidlock); 748 749 /* 750 * Return ENOENT immediately if there is no process. 751 */ 752 if (p == NULL) 753 return (ENOENT); 754 755 ASSERT(p == pcp->prc_proc && p->p_stat != 0 && p->p_stat != SIDL); 756 757 /* 758 * Return ENOENT if process entered zombie state or is exiting 759 * and the 'zdisp' flag is set to ZNO indicating not to lock zombies. 760 */ 761 if (zdisp == ZNO && 762 ((pcp->prc_flags & PRC_DESTROY) || (p->p_flag & SEXITING))) { 763 prunlock(pnp); 764 return (ENOENT); 765 } 766 767 /* 768 * If lwp-specific, check to see if lwp has disappeared. 769 */ 770 if (pcp->prc_flags & PRC_LWP) { 771 if ((zdisp == ZNO && (pcp->prc_flags & PRC_DESTROY)) || 772 pcp->prc_tslot == -1) { 773 prunlock(pnp); 774 return (ENOENT); 775 } 776 } 777 778 /* 779 * Return EAGAIN if we have encountered a security violation. 780 * (The process exec'd a set-id or unreadable executable file.) 781 */ 782 if (pnp->pr_flags & PR_INVAL) { 783 prunlock(pnp); 784 return (EAGAIN); 785 } 786 787 /* 788 * If process is undergoing an exec(), wait for 789 * completion and then start all over again. 790 */ 791 if (p->p_proc_flag & P_PR_EXEC) { 792 pcp = pnp->pr_pcommon; /* Put on the correct sleep queue */ 793 mutex_enter(&pcp->prc_mutex); 794 prunlock(pnp); 795 if (!cv_wait_sig(&pcp->prc_wait, &pcp->prc_mutex)) { 796 mutex_exit(&pcp->prc_mutex); 797 return (EINTR); 798 } 799 mutex_exit(&pcp->prc_mutex); 800 goto again; 801 } 802 803 /* 804 * We return holding p->p_lock. 805 */ 806 return (0); 807 } 808 809 /* 810 * Undo prlock() and pr_p_lock(). 811 * p->p_lock is still held; pr_pidlock is no longer held. 812 * 813 * prunmark() drops the P_PR_LOCK flag and wakes up another thread, 814 * if any, waiting for the flag to be dropped; it retains p->p_lock. 815 * 816 * prunlock() calls prunmark() and then drops p->p_lock. 817 */ 818 void 819 prunmark(proc_t *p) 820 { 821 ASSERT(p->p_proc_flag & P_PR_LOCK); 822 ASSERT(MUTEX_HELD(&p->p_lock)); 823 824 cv_signal(&pr_pid_cv[p->p_slot]); 825 p->p_proc_flag &= ~P_PR_LOCK; 826 THREAD_KPRI_RELEASE(); 827 } 828 829 void 830 prunlock(prnode_t *pnp) 831 { 832 prcommon_t *pcp = pnp->pr_common; 833 proc_t *p = pcp->prc_proc; 834 835 /* 836 * If we (or someone) gave it a SIGKILL, and it is not 837 * already a zombie, set it running unconditionally. 838 */ 839 if ((p->p_flag & SKILLED) && 840 !(p->p_flag & SEXITING) && 841 !(pcp->prc_flags & PRC_DESTROY) && 842 !((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot == -1)) 843 (void) pr_setrun(pnp, 0); 844 prunmark(p); 845 mutex_exit(&p->p_lock); 846 } 847 848 /* 849 * Called while holding p->p_lock to delay until the process is unlocked. 850 * We enter holding p->p_lock; p->p_lock is dropped and reacquired. 851 * The process cannot become locked again until p->p_lock is dropped. 852 */ 853 void 854 prbarrier(proc_t *p) 855 { 856 ASSERT(MUTEX_HELD(&p->p_lock)); 857 858 if (p->p_proc_flag & P_PR_LOCK) { 859 /* The process is locked; delay until not locked */ 860 uint_t slot = p->p_slot; 861 862 while (p->p_proc_flag & P_PR_LOCK) 863 cv_wait(&pr_pid_cv[slot], &p->p_lock); 864 cv_signal(&pr_pid_cv[slot]); 865 } 866 } 867 868 /* 869 * Return process/lwp status. 870 * The u-block is mapped in by this routine and unmapped at the end. 871 */ 872 void 873 prgetstatus(proc_t *p, pstatus_t *sp, zone_t *zp) 874 { 875 kthread_t *t; 876 877 ASSERT(MUTEX_HELD(&p->p_lock)); 878 879 t = prchoose(p); /* returns locked thread */ 880 ASSERT(t != NULL); 881 thread_unlock(t); 882 883 /* just bzero the process part, prgetlwpstatus() does the rest */ 884 bzero(sp, sizeof (pstatus_t) - sizeof (lwpstatus_t)); 885 sp->pr_nlwp = p->p_lwpcnt; 886 sp->pr_nzomb = p->p_zombcnt; 887 prassignset(&sp->pr_sigpend, &p->p_sig); 888 sp->pr_brkbase = (uintptr_t)p->p_brkbase; 889 sp->pr_brksize = p->p_brksize; 890 sp->pr_stkbase = (uintptr_t)prgetstackbase(p); 891 sp->pr_stksize = p->p_stksize; 892 sp->pr_pid = p->p_pid; 893 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 894 (p->p_flag & SZONETOP)) { 895 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 896 /* 897 * Inside local zones, fake zsched's pid as parent pids for 898 * processes which reference processes outside of the zone. 899 */ 900 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 901 } else { 902 sp->pr_ppid = p->p_ppid; 903 } 904 sp->pr_pgid = p->p_pgrp; 905 sp->pr_sid = p->p_sessp->s_sid; 906 sp->pr_taskid = p->p_task->tk_tkid; 907 sp->pr_projid = p->p_task->tk_proj->kpj_id; 908 sp->pr_zoneid = p->p_zone->zone_id; 909 hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime); 910 hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime); 911 TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime); 912 TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime); 913 prassignset(&sp->pr_sigtrace, &p->p_sigmask); 914 prassignset(&sp->pr_flttrace, &p->p_fltmask); 915 prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask); 916 prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask); 917 switch (p->p_model) { 918 case DATAMODEL_ILP32: 919 sp->pr_dmodel = PR_MODEL_ILP32; 920 break; 921 case DATAMODEL_LP64: 922 sp->pr_dmodel = PR_MODEL_LP64; 923 break; 924 } 925 if (p->p_agenttp) 926 sp->pr_agentid = p->p_agenttp->t_tid; 927 928 /* get the chosen lwp's status */ 929 prgetlwpstatus(t, &sp->pr_lwp, zp); 930 931 /* replicate the flags */ 932 sp->pr_flags = sp->pr_lwp.pr_flags; 933 } 934 935 #ifdef _SYSCALL32_IMPL 936 void 937 prgetlwpstatus32(kthread_t *t, lwpstatus32_t *sp, zone_t *zp) 938 { 939 proc_t *p = ttoproc(t); 940 klwp_t *lwp = ttolwp(t); 941 struct mstate *ms = &lwp->lwp_mstate; 942 hrtime_t usr, sys; 943 int flags; 944 ulong_t instr; 945 946 ASSERT(MUTEX_HELD(&p->p_lock)); 947 948 bzero(sp, sizeof (*sp)); 949 flags = 0L; 950 if (t->t_state == TS_STOPPED) { 951 flags |= PR_STOPPED; 952 if ((t->t_schedflag & TS_PSTART) == 0) 953 flags |= PR_ISTOP; 954 } else if (VSTOPPED(t)) { 955 flags |= PR_STOPPED|PR_ISTOP; 956 } 957 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP)) 958 flags |= PR_DSTOP; 959 if (lwp->lwp_asleep) 960 flags |= PR_ASLEEP; 961 if (t == p->p_agenttp) 962 flags |= PR_AGENT; 963 if (!(t->t_proc_flag & TP_TWAIT)) 964 flags |= PR_DETACH; 965 if (t->t_proc_flag & TP_DAEMON) 966 flags |= PR_DAEMON; 967 if (p->p_proc_flag & P_PR_FORK) 968 flags |= PR_FORK; 969 if (p->p_proc_flag & P_PR_RUNLCL) 970 flags |= PR_RLC; 971 if (p->p_proc_flag & P_PR_KILLCL) 972 flags |= PR_KLC; 973 if (p->p_proc_flag & P_PR_ASYNC) 974 flags |= PR_ASYNC; 975 if (p->p_proc_flag & P_PR_BPTADJ) 976 flags |= PR_BPTADJ; 977 if (p->p_proc_flag & P_PR_PTRACE) 978 flags |= PR_PTRACE; 979 if (p->p_flag & SMSACCT) 980 flags |= PR_MSACCT; 981 if (p->p_flag & SMSFORK) 982 flags |= PR_MSFORK; 983 if (p->p_flag & SVFWAIT) 984 flags |= PR_VFORKP; 985 sp->pr_flags = flags; 986 if (VSTOPPED(t)) { 987 sp->pr_why = PR_REQUESTED; 988 sp->pr_what = 0; 989 } else { 990 sp->pr_why = t->t_whystop; 991 sp->pr_what = t->t_whatstop; 992 } 993 sp->pr_lwpid = t->t_tid; 994 sp->pr_cursig = lwp->lwp_cursig; 995 prassignset(&sp->pr_lwppend, &t->t_sig); 996 schedctl_finish_sigblock(t); 997 prassignset(&sp->pr_lwphold, &t->t_hold); 998 if (t->t_whystop == PR_FAULTED) { 999 siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info); 1000 if (t->t_whatstop == FLTPAGE) 1001 sp->pr_info.si_addr = 1002 (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr; 1003 } else if (lwp->lwp_curinfo) 1004 siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info); 1005 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID && 1006 sp->pr_info.si_zoneid != zp->zone_id) { 1007 sp->pr_info.si_pid = zp->zone_zsched->p_pid; 1008 sp->pr_info.si_uid = 0; 1009 sp->pr_info.si_ctid = -1; 1010 sp->pr_info.si_zoneid = zp->zone_id; 1011 } 1012 sp->pr_altstack.ss_sp = 1013 (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp; 1014 sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size; 1015 sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags; 1016 prgetaction32(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action); 1017 sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext; 1018 sp->pr_ustack = (caddr32_t)lwp->lwp_ustack; 1019 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name, 1020 sizeof (sp->pr_clname) - 1); 1021 if (flags & PR_STOPPED) 1022 hrt2ts32(t->t_stoptime, &sp->pr_tstamp); 1023 usr = ms->ms_acct[LMS_USER]; 1024 sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP]; 1025 scalehrtime(&usr); 1026 scalehrtime(&sys); 1027 hrt2ts32(usr, &sp->pr_utime); 1028 hrt2ts32(sys, &sp->pr_stime); 1029 1030 /* 1031 * Fetch the current instruction, if not a system process. 1032 * We don't attempt this unless the lwp is stopped. 1033 */ 1034 if ((p->p_flag & SSYS) || p->p_as == &kas) 1035 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL); 1036 else if (!(flags & PR_STOPPED)) 1037 sp->pr_flags |= PR_PCINVAL; 1038 else if (!prfetchinstr(lwp, &instr)) 1039 sp->pr_flags |= PR_PCINVAL; 1040 else 1041 sp->pr_instr = (uint32_t)instr; 1042 1043 /* 1044 * Drop p_lock while touching the lwp's stack. 1045 */ 1046 mutex_exit(&p->p_lock); 1047 if (prisstep(lwp)) 1048 sp->pr_flags |= PR_STEP; 1049 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) { 1050 int i; 1051 1052 sp->pr_syscall = get_syscall32_args(lwp, 1053 (int *)sp->pr_sysarg, &i); 1054 sp->pr_nsysarg = (ushort_t)i; 1055 } 1056 if ((flags & PR_STOPPED) || t == curthread) 1057 prgetprregs32(lwp, sp->pr_reg); 1058 if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) || 1059 (flags & PR_VFORKP)) { 1060 long r1, r2; 1061 user_t *up; 1062 auxv_t *auxp; 1063 int i; 1064 1065 sp->pr_errno = prgetrvals(lwp, &r1, &r2); 1066 if (sp->pr_errno == 0) { 1067 sp->pr_rval1 = (int32_t)r1; 1068 sp->pr_rval2 = (int32_t)r2; 1069 sp->pr_errpriv = PRIV_NONE; 1070 } else 1071 sp->pr_errpriv = lwp->lwp_badpriv; 1072 1073 if (t->t_sysnum == SYS_execve) { 1074 up = PTOU(p); 1075 sp->pr_sysarg[0] = 0; 1076 sp->pr_sysarg[1] = (caddr32_t)up->u_argv; 1077 sp->pr_sysarg[2] = (caddr32_t)up->u_envp; 1078 for (i = 0, auxp = up->u_auxv; 1079 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]); 1080 i++, auxp++) { 1081 if (auxp->a_type == AT_SUN_EXECNAME) { 1082 sp->pr_sysarg[0] = 1083 (caddr32_t) 1084 (uintptr_t)auxp->a_un.a_ptr; 1085 break; 1086 } 1087 } 1088 } 1089 } 1090 if (prhasfp()) 1091 prgetprfpregs32(lwp, &sp->pr_fpreg); 1092 mutex_enter(&p->p_lock); 1093 } 1094 1095 void 1096 prgetstatus32(proc_t *p, pstatus32_t *sp, zone_t *zp) 1097 { 1098 kthread_t *t; 1099 1100 ASSERT(MUTEX_HELD(&p->p_lock)); 1101 1102 t = prchoose(p); /* returns locked thread */ 1103 ASSERT(t != NULL); 1104 thread_unlock(t); 1105 1106 /* just bzero the process part, prgetlwpstatus32() does the rest */ 1107 bzero(sp, sizeof (pstatus32_t) - sizeof (lwpstatus32_t)); 1108 sp->pr_nlwp = p->p_lwpcnt; 1109 sp->pr_nzomb = p->p_zombcnt; 1110 prassignset(&sp->pr_sigpend, &p->p_sig); 1111 sp->pr_brkbase = (uint32_t)(uintptr_t)p->p_brkbase; 1112 sp->pr_brksize = (uint32_t)p->p_brksize; 1113 sp->pr_stkbase = (uint32_t)(uintptr_t)prgetstackbase(p); 1114 sp->pr_stksize = (uint32_t)p->p_stksize; 1115 sp->pr_pid = p->p_pid; 1116 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 1117 (p->p_flag & SZONETOP)) { 1118 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 1119 /* 1120 * Inside local zones, fake zsched's pid as parent pids for 1121 * processes which reference processes outside of the zone. 1122 */ 1123 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 1124 } else { 1125 sp->pr_ppid = p->p_ppid; 1126 } 1127 sp->pr_pgid = p->p_pgrp; 1128 sp->pr_sid = p->p_sessp->s_sid; 1129 sp->pr_taskid = p->p_task->tk_tkid; 1130 sp->pr_projid = p->p_task->tk_proj->kpj_id; 1131 sp->pr_zoneid = p->p_zone->zone_id; 1132 hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime); 1133 hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime); 1134 TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime); 1135 TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime); 1136 prassignset(&sp->pr_sigtrace, &p->p_sigmask); 1137 prassignset(&sp->pr_flttrace, &p->p_fltmask); 1138 prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask); 1139 prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask); 1140 switch (p->p_model) { 1141 case DATAMODEL_ILP32: 1142 sp->pr_dmodel = PR_MODEL_ILP32; 1143 break; 1144 case DATAMODEL_LP64: 1145 sp->pr_dmodel = PR_MODEL_LP64; 1146 break; 1147 } 1148 if (p->p_agenttp) 1149 sp->pr_agentid = p->p_agenttp->t_tid; 1150 1151 /* get the chosen lwp's status */ 1152 prgetlwpstatus32(t, &sp->pr_lwp, zp); 1153 1154 /* replicate the flags */ 1155 sp->pr_flags = sp->pr_lwp.pr_flags; 1156 } 1157 #endif /* _SYSCALL32_IMPL */ 1158 1159 /* 1160 * Return lwp status. 1161 */ 1162 void 1163 prgetlwpstatus(kthread_t *t, lwpstatus_t *sp, zone_t *zp) 1164 { 1165 proc_t *p = ttoproc(t); 1166 klwp_t *lwp = ttolwp(t); 1167 struct mstate *ms = &lwp->lwp_mstate; 1168 hrtime_t usr, sys; 1169 int flags; 1170 ulong_t instr; 1171 1172 ASSERT(MUTEX_HELD(&p->p_lock)); 1173 1174 bzero(sp, sizeof (*sp)); 1175 flags = 0L; 1176 if (t->t_state == TS_STOPPED) { 1177 flags |= PR_STOPPED; 1178 if ((t->t_schedflag & TS_PSTART) == 0) 1179 flags |= PR_ISTOP; 1180 } else if (VSTOPPED(t)) { 1181 flags |= PR_STOPPED|PR_ISTOP; 1182 } 1183 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP)) 1184 flags |= PR_DSTOP; 1185 if (lwp->lwp_asleep) 1186 flags |= PR_ASLEEP; 1187 if (t == p->p_agenttp) 1188 flags |= PR_AGENT; 1189 if (!(t->t_proc_flag & TP_TWAIT)) 1190 flags |= PR_DETACH; 1191 if (t->t_proc_flag & TP_DAEMON) 1192 flags |= PR_DAEMON; 1193 if (p->p_proc_flag & P_PR_FORK) 1194 flags |= PR_FORK; 1195 if (p->p_proc_flag & P_PR_RUNLCL) 1196 flags |= PR_RLC; 1197 if (p->p_proc_flag & P_PR_KILLCL) 1198 flags |= PR_KLC; 1199 if (p->p_proc_flag & P_PR_ASYNC) 1200 flags |= PR_ASYNC; 1201 if (p->p_proc_flag & P_PR_BPTADJ) 1202 flags |= PR_BPTADJ; 1203 if (p->p_proc_flag & P_PR_PTRACE) 1204 flags |= PR_PTRACE; 1205 if (p->p_flag & SMSACCT) 1206 flags |= PR_MSACCT; 1207 if (p->p_flag & SMSFORK) 1208 flags |= PR_MSFORK; 1209 if (p->p_flag & SVFWAIT) 1210 flags |= PR_VFORKP; 1211 if (p->p_pgidp->pid_pgorphaned) 1212 flags |= PR_ORPHAN; 1213 if (p->p_pidflag & CLDNOSIGCHLD) 1214 flags |= PR_NOSIGCHLD; 1215 if (p->p_pidflag & CLDWAITPID) 1216 flags |= PR_WAITPID; 1217 sp->pr_flags = flags; 1218 if (VSTOPPED(t)) { 1219 sp->pr_why = PR_REQUESTED; 1220 sp->pr_what = 0; 1221 } else { 1222 sp->pr_why = t->t_whystop; 1223 sp->pr_what = t->t_whatstop; 1224 } 1225 sp->pr_lwpid = t->t_tid; 1226 sp->pr_cursig = lwp->lwp_cursig; 1227 prassignset(&sp->pr_lwppend, &t->t_sig); 1228 schedctl_finish_sigblock(t); 1229 prassignset(&sp->pr_lwphold, &t->t_hold); 1230 if (t->t_whystop == PR_FAULTED) 1231 bcopy(&lwp->lwp_siginfo, 1232 &sp->pr_info, sizeof (k_siginfo_t)); 1233 else if (lwp->lwp_curinfo) 1234 bcopy(&lwp->lwp_curinfo->sq_info, 1235 &sp->pr_info, sizeof (k_siginfo_t)); 1236 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID && 1237 sp->pr_info.si_zoneid != zp->zone_id) { 1238 sp->pr_info.si_pid = zp->zone_zsched->p_pid; 1239 sp->pr_info.si_uid = 0; 1240 sp->pr_info.si_ctid = -1; 1241 sp->pr_info.si_zoneid = zp->zone_id; 1242 } 1243 sp->pr_altstack = lwp->lwp_sigaltstack; 1244 prgetaction(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action); 1245 sp->pr_oldcontext = (uintptr_t)lwp->lwp_oldcontext; 1246 sp->pr_ustack = lwp->lwp_ustack; 1247 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name, 1248 sizeof (sp->pr_clname) - 1); 1249 if (flags & PR_STOPPED) 1250 hrt2ts(t->t_stoptime, &sp->pr_tstamp); 1251 usr = ms->ms_acct[LMS_USER]; 1252 sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP]; 1253 scalehrtime(&usr); 1254 scalehrtime(&sys); 1255 hrt2ts(usr, &sp->pr_utime); 1256 hrt2ts(sys, &sp->pr_stime); 1257 1258 /* 1259 * Fetch the current instruction, if not a system process. 1260 * We don't attempt this unless the lwp is stopped. 1261 */ 1262 if ((p->p_flag & SSYS) || p->p_as == &kas) 1263 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL); 1264 else if (!(flags & PR_STOPPED)) 1265 sp->pr_flags |= PR_PCINVAL; 1266 else if (!prfetchinstr(lwp, &instr)) 1267 sp->pr_flags |= PR_PCINVAL; 1268 else 1269 sp->pr_instr = instr; 1270 1271 /* 1272 * Drop p_lock while touching the lwp's stack. 1273 */ 1274 mutex_exit(&p->p_lock); 1275 if (prisstep(lwp)) 1276 sp->pr_flags |= PR_STEP; 1277 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) { 1278 int i; 1279 1280 sp->pr_syscall = get_syscall_args(lwp, 1281 (long *)sp->pr_sysarg, &i); 1282 sp->pr_nsysarg = (ushort_t)i; 1283 } 1284 if ((flags & PR_STOPPED) || t == curthread) 1285 prgetprregs(lwp, sp->pr_reg); 1286 if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) || 1287 (flags & PR_VFORKP)) { 1288 user_t *up; 1289 auxv_t *auxp; 1290 int i; 1291 1292 sp->pr_errno = prgetrvals(lwp, &sp->pr_rval1, &sp->pr_rval2); 1293 if (sp->pr_errno == 0) 1294 sp->pr_errpriv = PRIV_NONE; 1295 else 1296 sp->pr_errpriv = lwp->lwp_badpriv; 1297 1298 if (t->t_sysnum == SYS_execve) { 1299 up = PTOU(p); 1300 sp->pr_sysarg[0] = 0; 1301 sp->pr_sysarg[1] = (uintptr_t)up->u_argv; 1302 sp->pr_sysarg[2] = (uintptr_t)up->u_envp; 1303 for (i = 0, auxp = up->u_auxv; 1304 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]); 1305 i++, auxp++) { 1306 if (auxp->a_type == AT_SUN_EXECNAME) { 1307 sp->pr_sysarg[0] = 1308 (uintptr_t)auxp->a_un.a_ptr; 1309 break; 1310 } 1311 } 1312 } 1313 } 1314 if (prhasfp()) 1315 prgetprfpregs(lwp, &sp->pr_fpreg); 1316 mutex_enter(&p->p_lock); 1317 } 1318 1319 /* 1320 * Get the sigaction structure for the specified signal. The u-block 1321 * must already have been mapped in by the caller. 1322 */ 1323 void 1324 prgetaction(proc_t *p, user_t *up, uint_t sig, struct sigaction *sp) 1325 { 1326 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 1327 1328 bzero(sp, sizeof (*sp)); 1329 1330 if (sig != 0 && (unsigned)sig < nsig) { 1331 sp->sa_handler = up->u_signal[sig-1]; 1332 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]); 1333 if (sigismember(&up->u_sigonstack, sig)) 1334 sp->sa_flags |= SA_ONSTACK; 1335 if (sigismember(&up->u_sigresethand, sig)) 1336 sp->sa_flags |= SA_RESETHAND; 1337 if (sigismember(&up->u_sigrestart, sig)) 1338 sp->sa_flags |= SA_RESTART; 1339 if (sigismember(&p->p_siginfo, sig)) 1340 sp->sa_flags |= SA_SIGINFO; 1341 if (sigismember(&up->u_signodefer, sig)) 1342 sp->sa_flags |= SA_NODEFER; 1343 if (sig == SIGCLD) { 1344 if (p->p_flag & SNOWAIT) 1345 sp->sa_flags |= SA_NOCLDWAIT; 1346 if ((p->p_flag & SJCTL) == 0) 1347 sp->sa_flags |= SA_NOCLDSTOP; 1348 } 1349 } 1350 } 1351 1352 #ifdef _SYSCALL32_IMPL 1353 void 1354 prgetaction32(proc_t *p, user_t *up, uint_t sig, struct sigaction32 *sp) 1355 { 1356 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG; 1357 1358 bzero(sp, sizeof (*sp)); 1359 1360 if (sig != 0 && (unsigned)sig < nsig) { 1361 sp->sa_handler = (caddr32_t)(uintptr_t)up->u_signal[sig-1]; 1362 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]); 1363 if (sigismember(&up->u_sigonstack, sig)) 1364 sp->sa_flags |= SA_ONSTACK; 1365 if (sigismember(&up->u_sigresethand, sig)) 1366 sp->sa_flags |= SA_RESETHAND; 1367 if (sigismember(&up->u_sigrestart, sig)) 1368 sp->sa_flags |= SA_RESTART; 1369 if (sigismember(&p->p_siginfo, sig)) 1370 sp->sa_flags |= SA_SIGINFO; 1371 if (sigismember(&up->u_signodefer, sig)) 1372 sp->sa_flags |= SA_NODEFER; 1373 if (sig == SIGCLD) { 1374 if (p->p_flag & SNOWAIT) 1375 sp->sa_flags |= SA_NOCLDWAIT; 1376 if ((p->p_flag & SJCTL) == 0) 1377 sp->sa_flags |= SA_NOCLDSTOP; 1378 } 1379 } 1380 } 1381 #endif /* _SYSCALL32_IMPL */ 1382 1383 /* 1384 * Count the number of segments in this process's address space. 1385 */ 1386 int 1387 prnsegs(struct as *as, int reserved) 1388 { 1389 int n = 0; 1390 struct seg *seg; 1391 1392 ASSERT(as != &kas && AS_WRITE_HELD(as)); 1393 1394 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) { 1395 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved); 1396 caddr_t saddr, naddr; 1397 void *tmp = NULL; 1398 1399 if ((seg->s_flags & S_HOLE) != 0) { 1400 continue; 1401 } 1402 1403 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 1404 (void) pr_getprot(seg, reserved, &tmp, 1405 &saddr, &naddr, eaddr); 1406 if (saddr != naddr) 1407 n++; 1408 } 1409 1410 ASSERT(tmp == NULL); 1411 } 1412 1413 return (n); 1414 } 1415 1416 /* 1417 * Convert uint32_t to decimal string w/o leading zeros. 1418 * Add trailing null characters if 'len' is greater than string length. 1419 * Return the string length. 1420 */ 1421 int 1422 pr_u32tos(uint32_t n, char *s, int len) 1423 { 1424 char cbuf[11]; /* 32-bit unsigned integer fits in 10 digits */ 1425 char *cp = cbuf; 1426 char *end = s + len; 1427 1428 do { 1429 *cp++ = (char)(n % 10 + '0'); 1430 n /= 10; 1431 } while (n); 1432 1433 len = (int)(cp - cbuf); 1434 1435 do { 1436 *s++ = *--cp; 1437 } while (cp > cbuf); 1438 1439 while (s < end) /* optional pad */ 1440 *s++ = '\0'; 1441 1442 return (len); 1443 } 1444 1445 /* 1446 * Convert uint64_t to decimal string w/o leading zeros. 1447 * Return the string length. 1448 */ 1449 static int 1450 pr_u64tos(uint64_t n, char *s) 1451 { 1452 char cbuf[21]; /* 64-bit unsigned integer fits in 20 digits */ 1453 char *cp = cbuf; 1454 int len; 1455 1456 do { 1457 *cp++ = (char)(n % 10 + '0'); 1458 n /= 10; 1459 } while (n); 1460 1461 len = (int)(cp - cbuf); 1462 1463 do { 1464 *s++ = *--cp; 1465 } while (cp > cbuf); 1466 1467 return (len); 1468 } 1469 1470 file_t * 1471 pr_getf(proc_t *p, uint_t fd, short *flag) 1472 { 1473 uf_entry_t *ufp; 1474 uf_info_t *fip; 1475 file_t *fp; 1476 1477 ASSERT(MUTEX_HELD(&p->p_lock) && (p->p_proc_flag & P_PR_LOCK)); 1478 1479 fip = P_FINFO(p); 1480 1481 if (fd >= fip->fi_nfiles) 1482 return (NULL); 1483 1484 mutex_exit(&p->p_lock); 1485 mutex_enter(&fip->fi_lock); 1486 UF_ENTER(ufp, fip, fd); 1487 if ((fp = ufp->uf_file) != NULL && fp->f_count > 0) { 1488 if (flag != NULL) 1489 *flag = ufp->uf_flag; 1490 ufp->uf_refcnt++; 1491 } else { 1492 fp = NULL; 1493 } 1494 UF_EXIT(ufp); 1495 mutex_exit(&fip->fi_lock); 1496 mutex_enter(&p->p_lock); 1497 1498 return (fp); 1499 } 1500 1501 void 1502 pr_releasef(proc_t *p, uint_t fd) 1503 { 1504 uf_entry_t *ufp; 1505 uf_info_t *fip; 1506 1507 ASSERT(MUTEX_HELD(&p->p_lock) && (p->p_proc_flag & P_PR_LOCK)); 1508 1509 fip = P_FINFO(p); 1510 1511 mutex_exit(&p->p_lock); 1512 mutex_enter(&fip->fi_lock); 1513 UF_ENTER(ufp, fip, fd); 1514 ASSERT3U(ufp->uf_refcnt, >, 0); 1515 ufp->uf_refcnt--; 1516 UF_EXIT(ufp); 1517 mutex_exit(&fip->fi_lock); 1518 mutex_enter(&p->p_lock); 1519 } 1520 1521 void 1522 pr_object_name(char *name, vnode_t *vp, struct vattr *vattr) 1523 { 1524 char *s = name; 1525 struct vfs *vfsp; 1526 struct vfssw *vfsswp; 1527 1528 if ((vfsp = vp->v_vfsp) != NULL && 1529 ((vfsswp = vfssw + vfsp->vfs_fstype), vfsswp->vsw_name) && 1530 *vfsswp->vsw_name) { 1531 (void) strcpy(s, vfsswp->vsw_name); 1532 s += strlen(s); 1533 *s++ = '.'; 1534 } 1535 s += pr_u32tos(getmajor(vattr->va_fsid), s, 0); 1536 *s++ = '.'; 1537 s += pr_u32tos(getminor(vattr->va_fsid), s, 0); 1538 *s++ = '.'; 1539 s += pr_u64tos(vattr->va_nodeid, s); 1540 *s++ = '\0'; 1541 } 1542 1543 struct seg * 1544 break_seg(proc_t *p) 1545 { 1546 caddr_t addr = p->p_brkbase; 1547 struct seg *seg; 1548 struct vnode *vp; 1549 1550 if (p->p_brksize != 0) 1551 addr += p->p_brksize - 1; 1552 seg = as_segat(p->p_as, addr); 1553 if (seg != NULL && seg->s_ops == &segvn_ops && 1554 (SEGOP_GETVP(seg, seg->s_base, &vp) != 0 || vp == NULL)) 1555 return (seg); 1556 return (NULL); 1557 } 1558 1559 /* 1560 * Implementation of service functions to handle procfs generic chained 1561 * copyout buffers. 1562 */ 1563 typedef struct pr_iobuf_list { 1564 list_node_t piol_link; /* buffer linkage */ 1565 size_t piol_size; /* total size (header + data) */ 1566 size_t piol_usedsize; /* amount to copy out from this buf */ 1567 } piol_t; 1568 1569 #define MAPSIZE (64 * 1024) 1570 #define PIOL_DATABUF(iol) ((void *)(&(iol)[1])) 1571 1572 void 1573 pr_iol_initlist(list_t *iolhead, size_t itemsize, int n) 1574 { 1575 piol_t *iol; 1576 size_t initial_size = MIN(1, n) * itemsize; 1577 1578 list_create(iolhead, sizeof (piol_t), offsetof(piol_t, piol_link)); 1579 1580 ASSERT(list_head(iolhead) == NULL); 1581 ASSERT(itemsize < MAPSIZE - sizeof (*iol)); 1582 ASSERT(initial_size > 0); 1583 1584 /* 1585 * Someone creating chained copyout buffers may ask for less than 1586 * MAPSIZE if the amount of data to be buffered is known to be 1587 * smaller than that. 1588 * But in order to prevent involuntary self-denial of service, 1589 * the requested input size is clamped at MAPSIZE. 1590 */ 1591 initial_size = MIN(MAPSIZE, initial_size + sizeof (*iol)); 1592 iol = kmem_alloc(initial_size, KM_SLEEP); 1593 list_insert_head(iolhead, iol); 1594 iol->piol_usedsize = 0; 1595 iol->piol_size = initial_size; 1596 } 1597 1598 void * 1599 pr_iol_newbuf(list_t *iolhead, size_t itemsize) 1600 { 1601 piol_t *iol; 1602 char *new; 1603 1604 ASSERT(itemsize < MAPSIZE - sizeof (*iol)); 1605 ASSERT(list_head(iolhead) != NULL); 1606 1607 iol = (piol_t *)list_tail(iolhead); 1608 1609 if (iol->piol_size < 1610 iol->piol_usedsize + sizeof (*iol) + itemsize) { 1611 /* 1612 * Out of space in the current buffer. Allocate more. 1613 */ 1614 piol_t *newiol; 1615 1616 newiol = kmem_alloc(MAPSIZE, KM_SLEEP); 1617 newiol->piol_size = MAPSIZE; 1618 newiol->piol_usedsize = 0; 1619 1620 list_insert_after(iolhead, iol, newiol); 1621 iol = list_next(iolhead, iol); 1622 ASSERT(iol == newiol); 1623 } 1624 new = (char *)PIOL_DATABUF(iol) + iol->piol_usedsize; 1625 iol->piol_usedsize += itemsize; 1626 bzero(new, itemsize); 1627 return (new); 1628 } 1629 1630 void 1631 pr_iol_freelist(list_t *iolhead) 1632 { 1633 piol_t *iol; 1634 1635 while ((iol = list_head(iolhead)) != NULL) { 1636 list_remove(iolhead, iol); 1637 kmem_free(iol, iol->piol_size); 1638 } 1639 list_destroy(iolhead); 1640 } 1641 1642 int 1643 pr_iol_copyout_and_free(list_t *iolhead, caddr_t *tgt, int errin) 1644 { 1645 int error = errin; 1646 piol_t *iol; 1647 1648 while ((iol = list_head(iolhead)) != NULL) { 1649 list_remove(iolhead, iol); 1650 if (!error) { 1651 if (copyout(PIOL_DATABUF(iol), *tgt, 1652 iol->piol_usedsize)) 1653 error = EFAULT; 1654 *tgt += iol->piol_usedsize; 1655 } 1656 kmem_free(iol, iol->piol_size); 1657 } 1658 list_destroy(iolhead); 1659 1660 return (error); 1661 } 1662 1663 int 1664 pr_iol_uiomove_and_free(list_t *iolhead, uio_t *uiop, int errin) 1665 { 1666 offset_t off = uiop->uio_offset; 1667 char *base; 1668 size_t size; 1669 piol_t *iol; 1670 int error = errin; 1671 1672 while ((iol = list_head(iolhead)) != NULL) { 1673 list_remove(iolhead, iol); 1674 base = PIOL_DATABUF(iol); 1675 size = iol->piol_usedsize; 1676 if (off <= size && error == 0 && uiop->uio_resid > 0) 1677 error = uiomove(base + off, size - off, 1678 UIO_READ, uiop); 1679 off = MAX(0, off - (offset_t)size); 1680 kmem_free(iol, iol->piol_size); 1681 } 1682 list_destroy(iolhead); 1683 1684 return (error); 1685 } 1686 1687 /* 1688 * Return an array of structures with memory map information. 1689 * We allocate here; the caller must deallocate. 1690 */ 1691 int 1692 prgetmap(proc_t *p, int reserved, list_t *iolhead) 1693 { 1694 struct as *as = p->p_as; 1695 prmap_t *mp; 1696 struct seg *seg; 1697 struct seg *brkseg, *stkseg; 1698 struct vnode *vp; 1699 struct vattr vattr; 1700 uint_t prot; 1701 1702 ASSERT(as != &kas && AS_WRITE_HELD(as)); 1703 1704 /* 1705 * Request an initial buffer size that doesn't waste memory 1706 * if the address space has only a small number of segments. 1707 */ 1708 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 1709 1710 if ((seg = AS_SEGFIRST(as)) == NULL) 1711 return (0); 1712 1713 brkseg = break_seg(p); 1714 stkseg = as_segat(as, prgetstackbase(p)); 1715 1716 do { 1717 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved); 1718 caddr_t saddr, naddr; 1719 void *tmp = NULL; 1720 1721 if ((seg->s_flags & S_HOLE) != 0) { 1722 continue; 1723 } 1724 1725 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 1726 prot = pr_getprot(seg, reserved, &tmp, 1727 &saddr, &naddr, eaddr); 1728 if (saddr == naddr) 1729 continue; 1730 1731 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 1732 1733 mp->pr_vaddr = (uintptr_t)saddr; 1734 mp->pr_size = naddr - saddr; 1735 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr); 1736 mp->pr_mflags = 0; 1737 if (prot & PROT_READ) 1738 mp->pr_mflags |= MA_READ; 1739 if (prot & PROT_WRITE) 1740 mp->pr_mflags |= MA_WRITE; 1741 if (prot & PROT_EXEC) 1742 mp->pr_mflags |= MA_EXEC; 1743 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 1744 mp->pr_mflags |= MA_SHARED; 1745 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE) 1746 mp->pr_mflags |= MA_NORESERVE; 1747 if (seg->s_ops == &segspt_shmops || 1748 (seg->s_ops == &segvn_ops && 1749 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL))) 1750 mp->pr_mflags |= MA_ANON; 1751 if (seg == brkseg) 1752 mp->pr_mflags |= MA_BREAK; 1753 else if (seg == stkseg) { 1754 mp->pr_mflags |= MA_STACK; 1755 if (reserved) { 1756 size_t maxstack = 1757 ((size_t)p->p_stk_ctl + 1758 PAGEOFFSET) & PAGEMASK; 1759 mp->pr_vaddr = 1760 (uintptr_t)prgetstackbase(p) + 1761 p->p_stksize - maxstack; 1762 mp->pr_size = (uintptr_t)naddr - 1763 mp->pr_vaddr; 1764 } 1765 } 1766 if (seg->s_ops == &segspt_shmops) 1767 mp->pr_mflags |= MA_ISM | MA_SHM; 1768 mp->pr_pagesize = PAGESIZE; 1769 1770 /* 1771 * Manufacture a filename for the "object" directory. 1772 */ 1773 vattr.va_mask = AT_FSID|AT_NODEID; 1774 if (seg->s_ops == &segvn_ops && 1775 SEGOP_GETVP(seg, saddr, &vp) == 0 && 1776 vp != NULL && vp->v_type == VREG && 1777 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) { 1778 if (vp == p->p_exec) 1779 (void) strcpy(mp->pr_mapname, "a.out"); 1780 else 1781 pr_object_name(mp->pr_mapname, 1782 vp, &vattr); 1783 } 1784 1785 /* 1786 * Get the SysV shared memory id, if any. 1787 */ 1788 if ((mp->pr_mflags & MA_SHARED) && p->p_segacct && 1789 (mp->pr_shmid = shmgetid(p, seg->s_base)) != 1790 SHMID_NONE) { 1791 if (mp->pr_shmid == SHMID_FREE) 1792 mp->pr_shmid = -1; 1793 1794 mp->pr_mflags |= MA_SHM; 1795 } else { 1796 mp->pr_shmid = -1; 1797 } 1798 } 1799 ASSERT(tmp == NULL); 1800 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 1801 1802 return (0); 1803 } 1804 1805 #ifdef _SYSCALL32_IMPL 1806 int 1807 prgetmap32(proc_t *p, int reserved, list_t *iolhead) 1808 { 1809 struct as *as = p->p_as; 1810 prmap32_t *mp; 1811 struct seg *seg; 1812 struct seg *brkseg, *stkseg; 1813 struct vnode *vp; 1814 struct vattr vattr; 1815 uint_t prot; 1816 1817 ASSERT(as != &kas && AS_WRITE_HELD(as)); 1818 1819 /* 1820 * Request an initial buffer size that doesn't waste memory 1821 * if the address space has only a small number of segments. 1822 */ 1823 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 1824 1825 if ((seg = AS_SEGFIRST(as)) == NULL) 1826 return (0); 1827 1828 brkseg = break_seg(p); 1829 stkseg = as_segat(as, prgetstackbase(p)); 1830 1831 do { 1832 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved); 1833 caddr_t saddr, naddr; 1834 void *tmp = NULL; 1835 1836 if ((seg->s_flags & S_HOLE) != 0) { 1837 continue; 1838 } 1839 1840 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 1841 prot = pr_getprot(seg, reserved, &tmp, 1842 &saddr, &naddr, eaddr); 1843 if (saddr == naddr) 1844 continue; 1845 1846 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 1847 1848 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr; 1849 mp->pr_size = (size32_t)(naddr - saddr); 1850 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr); 1851 mp->pr_mflags = 0; 1852 if (prot & PROT_READ) 1853 mp->pr_mflags |= MA_READ; 1854 if (prot & PROT_WRITE) 1855 mp->pr_mflags |= MA_WRITE; 1856 if (prot & PROT_EXEC) 1857 mp->pr_mflags |= MA_EXEC; 1858 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 1859 mp->pr_mflags |= MA_SHARED; 1860 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE) 1861 mp->pr_mflags |= MA_NORESERVE; 1862 if (seg->s_ops == &segspt_shmops || 1863 (seg->s_ops == &segvn_ops && 1864 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL))) 1865 mp->pr_mflags |= MA_ANON; 1866 if (seg == brkseg) 1867 mp->pr_mflags |= MA_BREAK; 1868 else if (seg == stkseg) { 1869 mp->pr_mflags |= MA_STACK; 1870 if (reserved) { 1871 size_t maxstack = 1872 ((size_t)p->p_stk_ctl + 1873 PAGEOFFSET) & PAGEMASK; 1874 uintptr_t vaddr = 1875 (uintptr_t)prgetstackbase(p) + 1876 p->p_stksize - maxstack; 1877 mp->pr_vaddr = (caddr32_t)vaddr; 1878 mp->pr_size = (size32_t) 1879 ((uintptr_t)naddr - vaddr); 1880 } 1881 } 1882 if (seg->s_ops == &segspt_shmops) 1883 mp->pr_mflags |= MA_ISM | MA_SHM; 1884 mp->pr_pagesize = PAGESIZE; 1885 1886 /* 1887 * Manufacture a filename for the "object" directory. 1888 */ 1889 vattr.va_mask = AT_FSID|AT_NODEID; 1890 if (seg->s_ops == &segvn_ops && 1891 SEGOP_GETVP(seg, saddr, &vp) == 0 && 1892 vp != NULL && vp->v_type == VREG && 1893 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) { 1894 if (vp == p->p_exec) 1895 (void) strcpy(mp->pr_mapname, "a.out"); 1896 else 1897 pr_object_name(mp->pr_mapname, 1898 vp, &vattr); 1899 } 1900 1901 /* 1902 * Get the SysV shared memory id, if any. 1903 */ 1904 if ((mp->pr_mflags & MA_SHARED) && p->p_segacct && 1905 (mp->pr_shmid = shmgetid(p, seg->s_base)) != 1906 SHMID_NONE) { 1907 if (mp->pr_shmid == SHMID_FREE) 1908 mp->pr_shmid = -1; 1909 1910 mp->pr_mflags |= MA_SHM; 1911 } else { 1912 mp->pr_shmid = -1; 1913 } 1914 } 1915 ASSERT(tmp == NULL); 1916 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 1917 1918 return (0); 1919 } 1920 #endif /* _SYSCALL32_IMPL */ 1921 1922 /* 1923 * Return the size of the /proc page data file. 1924 */ 1925 size_t 1926 prpdsize(struct as *as) 1927 { 1928 struct seg *seg; 1929 size_t size; 1930 1931 ASSERT(as != &kas && AS_WRITE_HELD(as)); 1932 1933 if ((seg = AS_SEGFIRST(as)) == NULL) 1934 return (0); 1935 1936 size = sizeof (prpageheader_t); 1937 do { 1938 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 1939 caddr_t saddr, naddr; 1940 void *tmp = NULL; 1941 size_t npage; 1942 1943 if ((seg->s_flags & S_HOLE) != 0) { 1944 continue; 1945 } 1946 1947 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 1948 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 1949 if ((npage = (naddr - saddr) / PAGESIZE) != 0) 1950 size += sizeof (prasmap_t) + round8(npage); 1951 } 1952 ASSERT(tmp == NULL); 1953 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 1954 1955 return (size); 1956 } 1957 1958 #ifdef _SYSCALL32_IMPL 1959 size_t 1960 prpdsize32(struct as *as) 1961 { 1962 struct seg *seg; 1963 size_t size; 1964 1965 ASSERT(as != &kas && AS_WRITE_HELD(as)); 1966 1967 if ((seg = AS_SEGFIRST(as)) == NULL) 1968 return (0); 1969 1970 size = sizeof (prpageheader32_t); 1971 do { 1972 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 1973 caddr_t saddr, naddr; 1974 void *tmp = NULL; 1975 size_t npage; 1976 1977 if ((seg->s_flags & S_HOLE) != 0) { 1978 continue; 1979 } 1980 1981 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 1982 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 1983 if ((npage = (naddr - saddr) / PAGESIZE) != 0) 1984 size += sizeof (prasmap32_t) + round8(npage); 1985 } 1986 ASSERT(tmp == NULL); 1987 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 1988 1989 return (size); 1990 } 1991 #endif /* _SYSCALL32_IMPL */ 1992 1993 /* 1994 * Read page data information. 1995 */ 1996 int 1997 prpdread(proc_t *p, uint_t hatid, struct uio *uiop) 1998 { 1999 struct as *as = p->p_as; 2000 caddr_t buf; 2001 size_t size; 2002 prpageheader_t *php; 2003 prasmap_t *pmp; 2004 struct seg *seg; 2005 int error; 2006 2007 again: 2008 AS_LOCK_ENTER(as, RW_WRITER); 2009 2010 if ((seg = AS_SEGFIRST(as)) == NULL) { 2011 AS_LOCK_EXIT(as); 2012 return (0); 2013 } 2014 size = prpdsize(as); 2015 if (uiop->uio_resid < size) { 2016 AS_LOCK_EXIT(as); 2017 return (E2BIG); 2018 } 2019 2020 buf = kmem_zalloc(size, KM_SLEEP); 2021 php = (prpageheader_t *)buf; 2022 pmp = (prasmap_t *)(buf + sizeof (prpageheader_t)); 2023 2024 hrt2ts(gethrtime(), &php->pr_tstamp); 2025 php->pr_nmap = 0; 2026 php->pr_npage = 0; 2027 do { 2028 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 2029 caddr_t saddr, naddr; 2030 void *tmp = NULL; 2031 2032 if ((seg->s_flags & S_HOLE) != 0) { 2033 continue; 2034 } 2035 2036 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 2037 struct vnode *vp; 2038 struct vattr vattr; 2039 size_t len; 2040 size_t npage; 2041 uint_t prot; 2042 uintptr_t next; 2043 2044 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 2045 if ((len = (size_t)(naddr - saddr)) == 0) 2046 continue; 2047 npage = len / PAGESIZE; 2048 next = (uintptr_t)(pmp + 1) + round8(npage); 2049 /* 2050 * It's possible that the address space can change 2051 * subtlely even though we're holding as->a_lock 2052 * due to the nondeterminism of page_exists() in 2053 * the presence of asychronously flushed pages or 2054 * mapped files whose sizes are changing. 2055 * page_exists() may be called indirectly from 2056 * pr_getprot() by a SEGOP_INCORE() routine. 2057 * If this happens we need to make sure we don't 2058 * overrun the buffer whose size we computed based 2059 * on the initial iteration through the segments. 2060 * Once we've detected an overflow, we need to clean 2061 * up the temporary memory allocated in pr_getprot() 2062 * and retry. If there's a pending signal, we return 2063 * EINTR so that this thread can be dislodged if 2064 * a latent bug causes us to spin indefinitely. 2065 */ 2066 if (next > (uintptr_t)buf + size) { 2067 pr_getprot_done(&tmp); 2068 AS_LOCK_EXIT(as); 2069 2070 kmem_free(buf, size); 2071 2072 if (ISSIG(curthread, JUSTLOOKING)) 2073 return (EINTR); 2074 2075 goto again; 2076 } 2077 2078 php->pr_nmap++; 2079 php->pr_npage += npage; 2080 pmp->pr_vaddr = (uintptr_t)saddr; 2081 pmp->pr_npage = npage; 2082 pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr); 2083 pmp->pr_mflags = 0; 2084 if (prot & PROT_READ) 2085 pmp->pr_mflags |= MA_READ; 2086 if (prot & PROT_WRITE) 2087 pmp->pr_mflags |= MA_WRITE; 2088 if (prot & PROT_EXEC) 2089 pmp->pr_mflags |= MA_EXEC; 2090 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 2091 pmp->pr_mflags |= MA_SHARED; 2092 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE) 2093 pmp->pr_mflags |= MA_NORESERVE; 2094 if (seg->s_ops == &segspt_shmops || 2095 (seg->s_ops == &segvn_ops && 2096 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL))) 2097 pmp->pr_mflags |= MA_ANON; 2098 if (seg->s_ops == &segspt_shmops) 2099 pmp->pr_mflags |= MA_ISM | MA_SHM; 2100 pmp->pr_pagesize = PAGESIZE; 2101 /* 2102 * Manufacture a filename for the "object" directory. 2103 */ 2104 vattr.va_mask = AT_FSID|AT_NODEID; 2105 if (seg->s_ops == &segvn_ops && 2106 SEGOP_GETVP(seg, saddr, &vp) == 0 && 2107 vp != NULL && vp->v_type == VREG && 2108 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) { 2109 if (vp == p->p_exec) 2110 (void) strcpy(pmp->pr_mapname, "a.out"); 2111 else 2112 pr_object_name(pmp->pr_mapname, 2113 vp, &vattr); 2114 } 2115 2116 /* 2117 * Get the SysV shared memory id, if any. 2118 */ 2119 if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct && 2120 (pmp->pr_shmid = shmgetid(p, seg->s_base)) != 2121 SHMID_NONE) { 2122 if (pmp->pr_shmid == SHMID_FREE) 2123 pmp->pr_shmid = -1; 2124 2125 pmp->pr_mflags |= MA_SHM; 2126 } else { 2127 pmp->pr_shmid = -1; 2128 } 2129 2130 hat_getstat(as, saddr, len, hatid, 2131 (char *)(pmp + 1), HAT_SYNC_ZERORM); 2132 pmp = (prasmap_t *)next; 2133 } 2134 ASSERT(tmp == NULL); 2135 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 2136 2137 AS_LOCK_EXIT(as); 2138 2139 ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size); 2140 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop); 2141 kmem_free(buf, size); 2142 2143 return (error); 2144 } 2145 2146 #ifdef _SYSCALL32_IMPL 2147 int 2148 prpdread32(proc_t *p, uint_t hatid, struct uio *uiop) 2149 { 2150 struct as *as = p->p_as; 2151 caddr_t buf; 2152 size_t size; 2153 prpageheader32_t *php; 2154 prasmap32_t *pmp; 2155 struct seg *seg; 2156 int error; 2157 2158 again: 2159 AS_LOCK_ENTER(as, RW_WRITER); 2160 2161 if ((seg = AS_SEGFIRST(as)) == NULL) { 2162 AS_LOCK_EXIT(as); 2163 return (0); 2164 } 2165 size = prpdsize32(as); 2166 if (uiop->uio_resid < size) { 2167 AS_LOCK_EXIT(as); 2168 return (E2BIG); 2169 } 2170 2171 buf = kmem_zalloc(size, KM_SLEEP); 2172 php = (prpageheader32_t *)buf; 2173 pmp = (prasmap32_t *)(buf + sizeof (prpageheader32_t)); 2174 2175 hrt2ts32(gethrtime(), &php->pr_tstamp); 2176 php->pr_nmap = 0; 2177 php->pr_npage = 0; 2178 do { 2179 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 2180 caddr_t saddr, naddr; 2181 void *tmp = NULL; 2182 2183 if ((seg->s_flags & S_HOLE) != 0) { 2184 continue; 2185 } 2186 2187 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) { 2188 struct vnode *vp; 2189 struct vattr vattr; 2190 size_t len; 2191 size_t npage; 2192 uint_t prot; 2193 uintptr_t next; 2194 2195 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr); 2196 if ((len = (size_t)(naddr - saddr)) == 0) 2197 continue; 2198 npage = len / PAGESIZE; 2199 next = (uintptr_t)(pmp + 1) + round8(npage); 2200 /* 2201 * It's possible that the address space can change 2202 * subtlely even though we're holding as->a_lock 2203 * due to the nondeterminism of page_exists() in 2204 * the presence of asychronously flushed pages or 2205 * mapped files whose sizes are changing. 2206 * page_exists() may be called indirectly from 2207 * pr_getprot() by a SEGOP_INCORE() routine. 2208 * If this happens we need to make sure we don't 2209 * overrun the buffer whose size we computed based 2210 * on the initial iteration through the segments. 2211 * Once we've detected an overflow, we need to clean 2212 * up the temporary memory allocated in pr_getprot() 2213 * and retry. If there's a pending signal, we return 2214 * EINTR so that this thread can be dislodged if 2215 * a latent bug causes us to spin indefinitely. 2216 */ 2217 if (next > (uintptr_t)buf + size) { 2218 pr_getprot_done(&tmp); 2219 AS_LOCK_EXIT(as); 2220 2221 kmem_free(buf, size); 2222 2223 if (ISSIG(curthread, JUSTLOOKING)) 2224 return (EINTR); 2225 2226 goto again; 2227 } 2228 2229 php->pr_nmap++; 2230 php->pr_npage += npage; 2231 pmp->pr_vaddr = (caddr32_t)(uintptr_t)saddr; 2232 pmp->pr_npage = (size32_t)npage; 2233 pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr); 2234 pmp->pr_mflags = 0; 2235 if (prot & PROT_READ) 2236 pmp->pr_mflags |= MA_READ; 2237 if (prot & PROT_WRITE) 2238 pmp->pr_mflags |= MA_WRITE; 2239 if (prot & PROT_EXEC) 2240 pmp->pr_mflags |= MA_EXEC; 2241 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 2242 pmp->pr_mflags |= MA_SHARED; 2243 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE) 2244 pmp->pr_mflags |= MA_NORESERVE; 2245 if (seg->s_ops == &segspt_shmops || 2246 (seg->s_ops == &segvn_ops && 2247 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL))) 2248 pmp->pr_mflags |= MA_ANON; 2249 if (seg->s_ops == &segspt_shmops) 2250 pmp->pr_mflags |= MA_ISM | MA_SHM; 2251 pmp->pr_pagesize = PAGESIZE; 2252 /* 2253 * Manufacture a filename for the "object" directory. 2254 */ 2255 vattr.va_mask = AT_FSID|AT_NODEID; 2256 if (seg->s_ops == &segvn_ops && 2257 SEGOP_GETVP(seg, saddr, &vp) == 0 && 2258 vp != NULL && vp->v_type == VREG && 2259 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) { 2260 if (vp == p->p_exec) 2261 (void) strcpy(pmp->pr_mapname, "a.out"); 2262 else 2263 pr_object_name(pmp->pr_mapname, 2264 vp, &vattr); 2265 } 2266 2267 /* 2268 * Get the SysV shared memory id, if any. 2269 */ 2270 if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct && 2271 (pmp->pr_shmid = shmgetid(p, seg->s_base)) != 2272 SHMID_NONE) { 2273 if (pmp->pr_shmid == SHMID_FREE) 2274 pmp->pr_shmid = -1; 2275 2276 pmp->pr_mflags |= MA_SHM; 2277 } else { 2278 pmp->pr_shmid = -1; 2279 } 2280 2281 hat_getstat(as, saddr, len, hatid, 2282 (char *)(pmp + 1), HAT_SYNC_ZERORM); 2283 pmp = (prasmap32_t *)next; 2284 } 2285 ASSERT(tmp == NULL); 2286 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 2287 2288 AS_LOCK_EXIT(as); 2289 2290 ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size); 2291 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop); 2292 kmem_free(buf, size); 2293 2294 return (error); 2295 } 2296 #endif /* _SYSCALL32_IMPL */ 2297 2298 ushort_t 2299 prgetpctcpu(uint64_t pct) 2300 { 2301 /* 2302 * The value returned will be relevant in the zone of the examiner, 2303 * which may not be the same as the zone which performed the procfs 2304 * mount. 2305 */ 2306 int nonline = zone_ncpus_online_get(curproc->p_zone); 2307 2308 /* 2309 * Prorate over online cpus so we don't exceed 100% 2310 */ 2311 if (nonline > 1) 2312 pct /= nonline; 2313 pct >>= 16; /* convert to 16-bit scaled integer */ 2314 if (pct > 0x8000) /* might happen, due to rounding */ 2315 pct = 0x8000; 2316 return ((ushort_t)pct); 2317 } 2318 2319 /* 2320 * Return information used by ps(1). 2321 */ 2322 void 2323 prgetpsinfo(proc_t *p, psinfo_t *psp) 2324 { 2325 kthread_t *t; 2326 struct cred *cred; 2327 hrtime_t hrutime, hrstime; 2328 2329 ASSERT(MUTEX_HELD(&p->p_lock)); 2330 2331 if ((t = prchoose(p)) == NULL) /* returns locked thread */ 2332 bzero(psp, sizeof (*psp)); 2333 else { 2334 thread_unlock(t); 2335 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp)); 2336 } 2337 2338 /* 2339 * only export SSYS and SMSACCT; everything else is off-limits to 2340 * userland apps. 2341 */ 2342 psp->pr_flag = p->p_flag & (SSYS | SMSACCT); 2343 psp->pr_nlwp = p->p_lwpcnt; 2344 psp->pr_nzomb = p->p_zombcnt; 2345 mutex_enter(&p->p_crlock); 2346 cred = p->p_cred; 2347 psp->pr_uid = crgetruid(cred); 2348 psp->pr_euid = crgetuid(cred); 2349 psp->pr_gid = crgetrgid(cred); 2350 psp->pr_egid = crgetgid(cred); 2351 mutex_exit(&p->p_crlock); 2352 psp->pr_pid = p->p_pid; 2353 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 2354 (p->p_flag & SZONETOP)) { 2355 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 2356 /* 2357 * Inside local zones, fake zsched's pid as parent pids for 2358 * processes which reference processes outside of the zone. 2359 */ 2360 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 2361 } else { 2362 psp->pr_ppid = p->p_ppid; 2363 } 2364 psp->pr_pgid = p->p_pgrp; 2365 psp->pr_sid = p->p_sessp->s_sid; 2366 psp->pr_taskid = p->p_task->tk_tkid; 2367 psp->pr_projid = p->p_task->tk_proj->kpj_id; 2368 psp->pr_poolid = p->p_pool->pool_id; 2369 psp->pr_zoneid = p->p_zone->zone_id; 2370 if ((psp->pr_contract = PRCTID(p)) == 0) 2371 psp->pr_contract = -1; 2372 psp->pr_addr = (uintptr_t)prgetpsaddr(p); 2373 switch (p->p_model) { 2374 case DATAMODEL_ILP32: 2375 psp->pr_dmodel = PR_MODEL_ILP32; 2376 break; 2377 case DATAMODEL_LP64: 2378 psp->pr_dmodel = PR_MODEL_LP64; 2379 break; 2380 } 2381 hrutime = mstate_aggr_state(p, LMS_USER); 2382 hrstime = mstate_aggr_state(p, LMS_SYSTEM); 2383 hrt2ts((hrutime + hrstime), &psp->pr_time); 2384 TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime); 2385 2386 if (t == NULL) { 2387 int wcode = p->p_wcode; /* must be atomic read */ 2388 2389 if (wcode) 2390 psp->pr_wstat = wstat(wcode, p->p_wdata); 2391 psp->pr_ttydev = PRNODEV; 2392 psp->pr_lwp.pr_state = SZOMB; 2393 psp->pr_lwp.pr_sname = 'Z'; 2394 psp->pr_lwp.pr_bindpro = PBIND_NONE; 2395 psp->pr_lwp.pr_bindpset = PS_NONE; 2396 } else { 2397 user_t *up = PTOU(p); 2398 struct as *as; 2399 dev_t d; 2400 extern dev_t rwsconsdev, rconsdev, uconsdev; 2401 2402 d = cttydev(p); 2403 /* 2404 * If the controlling terminal is the real 2405 * or workstation console device, map to what the 2406 * user thinks is the console device. Handle case when 2407 * rwsconsdev or rconsdev is set to NODEV for Starfire. 2408 */ 2409 if ((d == rwsconsdev || d == rconsdev) && d != NODEV) 2410 d = uconsdev; 2411 psp->pr_ttydev = (d == NODEV) ? PRNODEV : d; 2412 psp->pr_start = up->u_start; 2413 bcopy(up->u_comm, psp->pr_fname, 2414 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1)); 2415 bcopy(up->u_psargs, psp->pr_psargs, 2416 MIN(PRARGSZ-1, PSARGSZ)); 2417 psp->pr_argc = up->u_argc; 2418 psp->pr_argv = up->u_argv; 2419 psp->pr_envp = up->u_envp; 2420 2421 /* get the chosen lwp's lwpsinfo */ 2422 prgetlwpsinfo(t, &psp->pr_lwp); 2423 2424 /* compute %cpu for the process */ 2425 if (p->p_lwpcnt == 1) 2426 psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu; 2427 else { 2428 uint64_t pct = 0; 2429 hrtime_t cur_time = gethrtime_unscaled(); 2430 2431 t = p->p_tlist; 2432 do { 2433 pct += cpu_update_pct(t, cur_time); 2434 } while ((t = t->t_forw) != p->p_tlist); 2435 2436 psp->pr_pctcpu = prgetpctcpu(pct); 2437 } 2438 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 2439 psp->pr_size = 0; 2440 psp->pr_rssize = 0; 2441 } else { 2442 mutex_exit(&p->p_lock); 2443 AS_LOCK_ENTER(as, RW_READER); 2444 psp->pr_size = btopr(as->a_resvsize) * 2445 (PAGESIZE / 1024); 2446 psp->pr_rssize = rm_asrss(as) * (PAGESIZE / 1024); 2447 psp->pr_pctmem = rm_pctmemory(as); 2448 AS_LOCK_EXIT(as); 2449 mutex_enter(&p->p_lock); 2450 } 2451 } 2452 } 2453 2454 static size_t 2455 prfdinfomisc(list_t *data, uint_t type, const void *val, size_t vlen) 2456 { 2457 pr_misc_header_t *misc; 2458 size_t len; 2459 2460 len = PRFDINFO_ROUNDUP(sizeof (*misc) + vlen); 2461 2462 if (data != NULL) { 2463 misc = pr_iol_newbuf(data, len); 2464 misc->pr_misc_type = type; 2465 misc->pr_misc_size = len; 2466 misc++; 2467 bcopy((char *)val, (char *)misc, vlen); 2468 } 2469 2470 return (len); 2471 } 2472 2473 /* 2474 * There's no elegant way to determine if a character device 2475 * supports TLI, so just check a hardcoded list of known TLI 2476 * devices. 2477 */ 2478 2479 static boolean_t 2480 pristli(vnode_t *vp) 2481 { 2482 static const char *tlidevs[] = { 2483 "udp", "udp6", "tcp", "tcp6" 2484 }; 2485 char *devname; 2486 uint_t i; 2487 2488 ASSERT(vp != NULL); 2489 2490 if (vp->v_type != VCHR || vp->v_stream == NULL || vp->v_rdev == 0) 2491 return (B_FALSE); 2492 2493 if ((devname = mod_major_to_name(getmajor(vp->v_rdev))) == NULL) 2494 return (B_FALSE); 2495 2496 for (i = 0; i < ARRAY_SIZE(tlidevs); i++) { 2497 if (strcmp(devname, tlidevs[i]) == 0) 2498 return (B_TRUE); 2499 } 2500 2501 return (B_FALSE); 2502 } 2503 2504 static size_t 2505 prfdinfopath(proc_t *p, vnode_t *vp, list_t *data, cred_t *cred) 2506 { 2507 char *pathname; 2508 size_t pathlen; 2509 size_t sz = 0; 2510 2511 pathlen = MAXPATHLEN + 1; 2512 pathname = kmem_alloc(pathlen, KM_SLEEP); 2513 2514 if (vnodetopath(NULL, vp, pathname, pathlen, cred) == 0) { 2515 sz += prfdinfomisc(data, PR_PATHNAME, 2516 pathname, strlen(pathname) + 1); 2517 } 2518 2519 kmem_free(pathname, pathlen); 2520 return (sz); 2521 } 2522 2523 static size_t 2524 prfdinfotlisockopt(vnode_t *vp, list_t *data, cred_t *cred) 2525 { 2526 strcmd_t strcmd; 2527 int32_t rval; 2528 size_t sz = 0; 2529 2530 strcmd.sc_cmd = TI_GETMYNAME; 2531 strcmd.sc_timeout = 1; 2532 strcmd.sc_len = STRCMDBUFSIZE; 2533 2534 if (VOP_IOCTL(vp, _I_CMD, (intptr_t)&strcmd, FKIOCTL, cred, 2535 &rval, NULL) == 0 && strcmd.sc_len > 0) { 2536 sz += prfdinfomisc(data, PR_SOCKETNAME, strcmd.sc_buf, 2537 strcmd.sc_len); 2538 } 2539 2540 strcmd.sc_cmd = TI_GETPEERNAME; 2541 strcmd.sc_timeout = 1; 2542 strcmd.sc_len = STRCMDBUFSIZE; 2543 2544 if (VOP_IOCTL(vp, _I_CMD, (intptr_t)&strcmd, FKIOCTL, cred, 2545 &rval, NULL) == 0 && strcmd.sc_len > 0) { 2546 sz += prfdinfomisc(data, PR_PEERSOCKNAME, strcmd.sc_buf, 2547 strcmd.sc_len); 2548 } 2549 2550 return (sz); 2551 } 2552 2553 static size_t 2554 prfdinfosockopt(vnode_t *vp, list_t *data, cred_t *cred) 2555 { 2556 sonode_t *so; 2557 socklen_t vlen; 2558 size_t sz = 0; 2559 uint_t i; 2560 2561 if (vp->v_stream != NULL) { 2562 so = VTOSO(vp->v_stream->sd_vnode); 2563 2564 if (so->so_version == SOV_STREAM) 2565 so = NULL; 2566 } else { 2567 so = VTOSO(vp); 2568 } 2569 2570 if (so == NULL) 2571 return (0); 2572 2573 DTRACE_PROBE1(sonode, sonode_t *, so); 2574 2575 /* prmisc - PR_SOCKETNAME */ 2576 2577 struct sockaddr_storage buf; 2578 struct sockaddr *name = (struct sockaddr *)&buf; 2579 2580 vlen = sizeof (buf); 2581 if (SOP_GETSOCKNAME(so, name, &vlen, cred) == 0 && vlen > 0) 2582 sz += prfdinfomisc(data, PR_SOCKETNAME, name, vlen); 2583 2584 /* prmisc - PR_PEERSOCKNAME */ 2585 2586 vlen = sizeof (buf); 2587 if (SOP_GETPEERNAME(so, name, &vlen, B_FALSE, cred) == 0 && vlen > 0) 2588 sz += prfdinfomisc(data, PR_PEERSOCKNAME, name, vlen); 2589 2590 /* prmisc - PR_SOCKOPTS_BOOL_OPTS */ 2591 2592 static struct boolopt { 2593 int level; 2594 int opt; 2595 int bopt; 2596 } boolopts[] = { 2597 { SOL_SOCKET, SO_DEBUG, PR_SO_DEBUG }, 2598 { SOL_SOCKET, SO_REUSEADDR, PR_SO_REUSEADDR }, 2599 #ifdef SO_REUSEPORT 2600 /* SmartOS and OmniOS have SO_REUSEPORT */ 2601 { SOL_SOCKET, SO_REUSEPORT, PR_SO_REUSEPORT }, 2602 #endif 2603 { SOL_SOCKET, SO_KEEPALIVE, PR_SO_KEEPALIVE }, 2604 { SOL_SOCKET, SO_DONTROUTE, PR_SO_DONTROUTE }, 2605 { SOL_SOCKET, SO_BROADCAST, PR_SO_BROADCAST }, 2606 { SOL_SOCKET, SO_OOBINLINE, PR_SO_OOBINLINE }, 2607 { SOL_SOCKET, SO_DGRAM_ERRIND, PR_SO_DGRAM_ERRIND }, 2608 { SOL_SOCKET, SO_ALLZONES, PR_SO_ALLZONES }, 2609 { SOL_SOCKET, SO_MAC_EXEMPT, PR_SO_MAC_EXEMPT }, 2610 { SOL_SOCKET, SO_MAC_IMPLICIT, PR_SO_MAC_IMPLICIT }, 2611 { SOL_SOCKET, SO_EXCLBIND, PR_SO_EXCLBIND }, 2612 { SOL_SOCKET, SO_VRRP, PR_SO_VRRP }, 2613 { IPPROTO_UDP, UDP_NAT_T_ENDPOINT, 2614 PR_UDP_NAT_T_ENDPOINT } 2615 }; 2616 prsockopts_bool_opts_t opts; 2617 int val; 2618 2619 if (data != NULL) { 2620 opts.prsock_bool_opts = 0; 2621 2622 for (i = 0; i < ARRAY_SIZE(boolopts); i++) { 2623 vlen = sizeof (val); 2624 if (SOP_GETSOCKOPT(so, boolopts[i].level, 2625 boolopts[i].opt, &val, &vlen, 0, cred) == 0 && 2626 val != 0) { 2627 opts.prsock_bool_opts |= boolopts[i].bopt; 2628 } 2629 } 2630 } 2631 2632 sz += prfdinfomisc(data, PR_SOCKOPTS_BOOL_OPTS, &opts, sizeof (opts)); 2633 2634 /* prmisc - PR_SOCKOPT_LINGER */ 2635 2636 struct linger l; 2637 2638 vlen = sizeof (l); 2639 if (SOP_GETSOCKOPT(so, SOL_SOCKET, SO_LINGER, &l, &vlen, 2640 0, cred) == 0 && vlen > 0) { 2641 sz += prfdinfomisc(data, PR_SOCKOPT_LINGER, &l, vlen); 2642 } 2643 2644 /* prmisc - PR_SOCKOPT_* int types */ 2645 2646 static struct sopt { 2647 int level; 2648 int opt; 2649 int bopt; 2650 } sopts[] = { 2651 { SOL_SOCKET, SO_TYPE, PR_SOCKOPT_TYPE }, 2652 { SOL_SOCKET, SO_SNDBUF, PR_SOCKOPT_SNDBUF }, 2653 { SOL_SOCKET, SO_RCVBUF, PR_SOCKOPT_RCVBUF } 2654 }; 2655 2656 for (i = 0; i < ARRAY_SIZE(sopts); i++) { 2657 vlen = sizeof (val); 2658 if (SOP_GETSOCKOPT(so, sopts[i].level, sopts[i].opt, 2659 &val, &vlen, 0, cred) == 0 && vlen > 0) { 2660 sz += prfdinfomisc(data, sopts[i].bopt, &val, vlen); 2661 } 2662 } 2663 2664 /* prmisc - PR_SOCKOPT_IP_NEXTHOP */ 2665 2666 in_addr_t nexthop_val; 2667 2668 vlen = sizeof (nexthop_val); 2669 if (SOP_GETSOCKOPT(so, IPPROTO_IP, IP_NEXTHOP, 2670 &nexthop_val, &vlen, 0, cred) == 0 && vlen > 0) { 2671 sz += prfdinfomisc(data, PR_SOCKOPT_IP_NEXTHOP, 2672 &nexthop_val, vlen); 2673 } 2674 2675 /* prmisc - PR_SOCKOPT_IPV6_NEXTHOP */ 2676 2677 struct sockaddr_in6 nexthop6_val; 2678 2679 vlen = sizeof (nexthop6_val); 2680 if (SOP_GETSOCKOPT(so, IPPROTO_IPV6, IPV6_NEXTHOP, 2681 &nexthop6_val, &vlen, 0, cred) == 0 && vlen > 0) { 2682 sz += prfdinfomisc(data, PR_SOCKOPT_IPV6_NEXTHOP, 2683 &nexthop6_val, vlen); 2684 } 2685 2686 /* prmisc - PR_SOCKOPT_TCP_CONGESTION */ 2687 2688 char cong[CC_ALGO_NAME_MAX]; 2689 2690 vlen = sizeof (cong); 2691 if (SOP_GETSOCKOPT(so, IPPROTO_TCP, TCP_CONGESTION, 2692 &cong, &vlen, 0, cred) == 0 && vlen > 0) { 2693 sz += prfdinfomisc(data, PR_SOCKOPT_TCP_CONGESTION, cong, vlen); 2694 } 2695 2696 /* prmisc - PR_SOCKFILTERS_PRIV */ 2697 2698 struct fil_info fi; 2699 2700 vlen = sizeof (fi); 2701 if (SOP_GETSOCKOPT(so, SOL_FILTER, FIL_LIST, 2702 &fi, &vlen, 0, cred) == 0 && vlen != 0) { 2703 pr_misc_header_t *misc; 2704 size_t len; 2705 2706 /* 2707 * We limit the number of returned filters to 32. 2708 * This is the maximum number that pfiles will print 2709 * anyway. 2710 */ 2711 vlen = MIN(32, fi.fi_pos + 1); 2712 vlen *= sizeof (fi); 2713 2714 len = PRFDINFO_ROUNDUP(sizeof (*misc) + vlen); 2715 sz += len; 2716 2717 if (data != NULL) { 2718 /* 2719 * So that the filter list can be built incrementally, 2720 * prfdinfomisc() is not used here. Instead we 2721 * allocate a buffer directly on the copyout list using 2722 * pr_iol_newbuf() 2723 */ 2724 misc = pr_iol_newbuf(data, len); 2725 misc->pr_misc_type = PR_SOCKFILTERS_PRIV; 2726 misc->pr_misc_size = len; 2727 misc++; 2728 len = vlen; 2729 if (SOP_GETSOCKOPT(so, SOL_FILTER, FIL_LIST, 2730 misc, &vlen, 0, cred) == 0) { 2731 /* 2732 * In case the number of filters has reduced 2733 * since the first call, explicitly zero out 2734 * any unpopulated space. 2735 */ 2736 if (vlen < len) 2737 bzero(misc + vlen, len - vlen); 2738 } else { 2739 /* Something went wrong, zero out the result */ 2740 bzero(misc, vlen); 2741 } 2742 } 2743 } 2744 2745 return (sz); 2746 } 2747 2748 u_offset_t 2749 prgetfdinfosize(proc_t *p, vnode_t *vp, cred_t *cred) 2750 { 2751 u_offset_t sz; 2752 2753 /* 2754 * All fdinfo files will be at least this big - 2755 * sizeof fdinfo struct + zero length trailer 2756 */ 2757 sz = offsetof(prfdinfo_t, pr_misc) + sizeof (pr_misc_header_t); 2758 2759 /* Pathname */ 2760 if (vp->v_type != VSOCK && vp->v_type != VDOOR) 2761 sz += prfdinfopath(p, vp, NULL, cred); 2762 2763 /* Socket options */ 2764 if (vp->v_type == VSOCK) 2765 sz += prfdinfosockopt(vp, NULL, cred); 2766 2767 /* TLI/XTI sockets */ 2768 if (pristli(vp)) 2769 sz += prfdinfotlisockopt(vp, NULL, cred); 2770 2771 return (sz); 2772 } 2773 2774 int 2775 prgetfdinfo(proc_t *p, vnode_t *vp, prfdinfo_t *fdinfo, cred_t *cred, 2776 cred_t *file_cred, list_t *data) 2777 { 2778 vattr_t vattr; 2779 int error; 2780 2781 /* 2782 * The buffer has been initialised to zero by pr_iol_newbuf(). 2783 * Initialise defaults for any values that should not default to zero. 2784 */ 2785 fdinfo->pr_uid = (uid_t)-1; 2786 fdinfo->pr_gid = (gid_t)-1; 2787 fdinfo->pr_size = -1; 2788 fdinfo->pr_locktype = F_UNLCK; 2789 fdinfo->pr_lockpid = -1; 2790 fdinfo->pr_locksysid = -1; 2791 fdinfo->pr_peerpid = -1; 2792 2793 /* Offset */ 2794 2795 /* 2796 * pr_offset has already been set from the underlying file_t. 2797 * Check if it is plausible and reset to -1 if not. 2798 */ 2799 if (fdinfo->pr_offset != -1 && 2800 VOP_SEEK(vp, 0, (offset_t *)&fdinfo->pr_offset, NULL) != 0) 2801 fdinfo->pr_offset = -1; 2802 2803 /* 2804 * Attributes 2805 * 2806 * We have two cred_t structures available here. 2807 * 'cred' is the caller's credential, and 'file_cred' is the credential 2808 * for the file being inspected. 2809 * 2810 * When looking up the file attributes, file_cred is used in order 2811 * that the correct ownership is set for doors and FIFOs. Since the 2812 * caller has permission to read the fdinfo file in proc, this does 2813 * not expose any additional information. 2814 */ 2815 vattr.va_mask = AT_STAT; 2816 if (VOP_GETATTR(vp, &vattr, 0, file_cred, NULL) == 0) { 2817 fdinfo->pr_major = getmajor(vattr.va_fsid); 2818 fdinfo->pr_minor = getminor(vattr.va_fsid); 2819 fdinfo->pr_rmajor = getmajor(vattr.va_rdev); 2820 fdinfo->pr_rminor = getminor(vattr.va_rdev); 2821 fdinfo->pr_ino = (ino64_t)vattr.va_nodeid; 2822 fdinfo->pr_size = (off64_t)vattr.va_size; 2823 fdinfo->pr_mode = VTTOIF(vattr.va_type) | vattr.va_mode; 2824 fdinfo->pr_uid = vattr.va_uid; 2825 fdinfo->pr_gid = vattr.va_gid; 2826 if (vp->v_type == VSOCK) 2827 fdinfo->pr_fileflags |= sock_getfasync(vp); 2828 } 2829 2830 /* locks */ 2831 2832 flock64_t bf; 2833 2834 bzero(&bf, sizeof (bf)); 2835 bf.l_type = F_WRLCK; 2836 2837 if (VOP_FRLOCK(vp, F_GETLK, &bf, 2838 (uint16_t)(fdinfo->pr_fileflags & 0xffff), 0, NULL, 2839 cred, NULL) == 0 && bf.l_type != F_UNLCK) { 2840 fdinfo->pr_locktype = bf.l_type; 2841 fdinfo->pr_lockpid = bf.l_pid; 2842 fdinfo->pr_locksysid = bf.l_sysid; 2843 } 2844 2845 /* peer cred */ 2846 2847 k_peercred_t kpc; 2848 2849 switch (vp->v_type) { 2850 case VFIFO: 2851 case VSOCK: { 2852 int32_t rval; 2853 2854 error = VOP_IOCTL(vp, _I_GETPEERCRED, (intptr_t)&kpc, 2855 FKIOCTL, cred, &rval, NULL); 2856 break; 2857 } 2858 case VCHR: { 2859 struct strioctl strioc; 2860 int32_t rval; 2861 2862 if (vp->v_stream == NULL) { 2863 error = ENOTSUP; 2864 break; 2865 } 2866 strioc.ic_cmd = _I_GETPEERCRED; 2867 strioc.ic_timout = INFTIM; 2868 strioc.ic_len = (int)sizeof (k_peercred_t); 2869 strioc.ic_dp = (char *)&kpc; 2870 2871 error = strdoioctl(vp->v_stream, &strioc, FNATIVE | FKIOCTL, 2872 STR_NOSIG | K_TO_K, cred, &rval); 2873 break; 2874 } 2875 default: 2876 error = ENOTSUP; 2877 break; 2878 } 2879 2880 if (error == 0 && kpc.pc_cr != NULL) { 2881 proc_t *peerp; 2882 2883 fdinfo->pr_peerpid = kpc.pc_cpid; 2884 2885 crfree(kpc.pc_cr); 2886 2887 mutex_enter(&pidlock); 2888 if ((peerp = prfind(fdinfo->pr_peerpid)) != NULL) { 2889 user_t *up; 2890 2891 mutex_enter(&peerp->p_lock); 2892 mutex_exit(&pidlock); 2893 2894 up = PTOU(peerp); 2895 bcopy(up->u_comm, fdinfo->pr_peername, 2896 MIN(sizeof (up->u_comm), 2897 sizeof (fdinfo->pr_peername) - 1)); 2898 2899 mutex_exit(&peerp->p_lock); 2900 } else { 2901 mutex_exit(&pidlock); 2902 } 2903 } 2904 2905 /* 2906 * Don't attempt to determine the vnode path for a socket or a door 2907 * as it will cause a linear scan of the dnlc table given there is no 2908 * v_path associated with the vnode. 2909 */ 2910 if (vp->v_type != VSOCK && vp->v_type != VDOOR) 2911 (void) prfdinfopath(p, vp, data, cred); 2912 2913 if (vp->v_type == VSOCK) 2914 (void) prfdinfosockopt(vp, data, cred); 2915 2916 /* TLI/XTI stream sockets */ 2917 if (pristli(vp)) 2918 (void) prfdinfotlisockopt(vp, data, cred); 2919 2920 /* 2921 * Add a terminating header with a zero size. 2922 */ 2923 pr_misc_header_t *misc; 2924 2925 misc = pr_iol_newbuf(data, sizeof (*misc)); 2926 misc->pr_misc_size = 0; 2927 misc->pr_misc_type = (uint_t)-1; 2928 2929 return (0); 2930 } 2931 2932 #ifdef _SYSCALL32_IMPL 2933 void 2934 prgetpsinfo32(proc_t *p, psinfo32_t *psp) 2935 { 2936 kthread_t *t; 2937 struct cred *cred; 2938 hrtime_t hrutime, hrstime; 2939 2940 ASSERT(MUTEX_HELD(&p->p_lock)); 2941 2942 if ((t = prchoose(p)) == NULL) /* returns locked thread */ 2943 bzero(psp, sizeof (*psp)); 2944 else { 2945 thread_unlock(t); 2946 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp)); 2947 } 2948 2949 /* 2950 * only export SSYS and SMSACCT; everything else is off-limits to 2951 * userland apps. 2952 */ 2953 psp->pr_flag = p->p_flag & (SSYS | SMSACCT); 2954 psp->pr_nlwp = p->p_lwpcnt; 2955 psp->pr_nzomb = p->p_zombcnt; 2956 mutex_enter(&p->p_crlock); 2957 cred = p->p_cred; 2958 psp->pr_uid = crgetruid(cred); 2959 psp->pr_euid = crgetuid(cred); 2960 psp->pr_gid = crgetrgid(cred); 2961 psp->pr_egid = crgetgid(cred); 2962 mutex_exit(&p->p_crlock); 2963 psp->pr_pid = p->p_pid; 2964 if (curproc->p_zone->zone_id != GLOBAL_ZONEID && 2965 (p->p_flag & SZONETOP)) { 2966 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID); 2967 /* 2968 * Inside local zones, fake zsched's pid as parent pids for 2969 * processes which reference processes outside of the zone. 2970 */ 2971 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid; 2972 } else { 2973 psp->pr_ppid = p->p_ppid; 2974 } 2975 psp->pr_pgid = p->p_pgrp; 2976 psp->pr_sid = p->p_sessp->s_sid; 2977 psp->pr_taskid = p->p_task->tk_tkid; 2978 psp->pr_projid = p->p_task->tk_proj->kpj_id; 2979 psp->pr_poolid = p->p_pool->pool_id; 2980 psp->pr_zoneid = p->p_zone->zone_id; 2981 if ((psp->pr_contract = PRCTID(p)) == 0) 2982 psp->pr_contract = -1; 2983 psp->pr_addr = 0; /* cannot represent 64-bit addr in 32 bits */ 2984 switch (p->p_model) { 2985 case DATAMODEL_ILP32: 2986 psp->pr_dmodel = PR_MODEL_ILP32; 2987 break; 2988 case DATAMODEL_LP64: 2989 psp->pr_dmodel = PR_MODEL_LP64; 2990 break; 2991 } 2992 hrutime = mstate_aggr_state(p, LMS_USER); 2993 hrstime = mstate_aggr_state(p, LMS_SYSTEM); 2994 hrt2ts32(hrutime + hrstime, &psp->pr_time); 2995 TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime); 2996 2997 if (t == NULL) { 2998 extern int wstat(int, int); /* needs a header file */ 2999 int wcode = p->p_wcode; /* must be atomic read */ 3000 3001 if (wcode) 3002 psp->pr_wstat = wstat(wcode, p->p_wdata); 3003 psp->pr_ttydev = PRNODEV32; 3004 psp->pr_lwp.pr_state = SZOMB; 3005 psp->pr_lwp.pr_sname = 'Z'; 3006 } else { 3007 user_t *up = PTOU(p); 3008 struct as *as; 3009 dev_t d; 3010 extern dev_t rwsconsdev, rconsdev, uconsdev; 3011 3012 d = cttydev(p); 3013 /* 3014 * If the controlling terminal is the real 3015 * or workstation console device, map to what the 3016 * user thinks is the console device. Handle case when 3017 * rwsconsdev or rconsdev is set to NODEV for Starfire. 3018 */ 3019 if ((d == rwsconsdev || d == rconsdev) && d != NODEV) 3020 d = uconsdev; 3021 (void) cmpldev(&psp->pr_ttydev, d); 3022 TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start); 3023 bcopy(up->u_comm, psp->pr_fname, 3024 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1)); 3025 bcopy(up->u_psargs, psp->pr_psargs, 3026 MIN(PRARGSZ-1, PSARGSZ)); 3027 psp->pr_argc = up->u_argc; 3028 psp->pr_argv = (caddr32_t)up->u_argv; 3029 psp->pr_envp = (caddr32_t)up->u_envp; 3030 3031 /* get the chosen lwp's lwpsinfo */ 3032 prgetlwpsinfo32(t, &psp->pr_lwp); 3033 3034 /* compute %cpu for the process */ 3035 if (p->p_lwpcnt == 1) 3036 psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu; 3037 else { 3038 uint64_t pct = 0; 3039 hrtime_t cur_time; 3040 3041 t = p->p_tlist; 3042 cur_time = gethrtime_unscaled(); 3043 do { 3044 pct += cpu_update_pct(t, cur_time); 3045 } while ((t = t->t_forw) != p->p_tlist); 3046 3047 psp->pr_pctcpu = prgetpctcpu(pct); 3048 } 3049 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) { 3050 psp->pr_size = 0; 3051 psp->pr_rssize = 0; 3052 } else { 3053 mutex_exit(&p->p_lock); 3054 AS_LOCK_ENTER(as, RW_READER); 3055 psp->pr_size = (size32_t) 3056 (btopr(as->a_resvsize) * (PAGESIZE / 1024)); 3057 psp->pr_rssize = (size32_t) 3058 (rm_asrss(as) * (PAGESIZE / 1024)); 3059 psp->pr_pctmem = rm_pctmemory(as); 3060 AS_LOCK_EXIT(as); 3061 mutex_enter(&p->p_lock); 3062 } 3063 } 3064 3065 /* 3066 * If we are looking at an LP64 process, zero out 3067 * the fields that cannot be represented in ILP32. 3068 */ 3069 if (p->p_model != DATAMODEL_ILP32) { 3070 psp->pr_size = 0; 3071 psp->pr_rssize = 0; 3072 psp->pr_argv = 0; 3073 psp->pr_envp = 0; 3074 } 3075 } 3076 3077 #endif /* _SYSCALL32_IMPL */ 3078 3079 void 3080 prgetlwpsinfo(kthread_t *t, lwpsinfo_t *psp) 3081 { 3082 klwp_t *lwp = ttolwp(t); 3083 sobj_ops_t *sobj; 3084 char c, state; 3085 uint64_t pct; 3086 int retval, niceval; 3087 hrtime_t hrutime, hrstime; 3088 3089 ASSERT(MUTEX_HELD(&ttoproc(t)->p_lock)); 3090 3091 bzero(psp, sizeof (*psp)); 3092 3093 psp->pr_flag = 0; /* lwpsinfo_t.pr_flag is deprecated */ 3094 psp->pr_lwpid = t->t_tid; 3095 psp->pr_addr = (uintptr_t)t; 3096 psp->pr_wchan = (uintptr_t)t->t_wchan; 3097 3098 /* map the thread state enum into a process state enum */ 3099 state = VSTOPPED(t) ? TS_STOPPED : t->t_state; 3100 switch (state) { 3101 case TS_SLEEP: state = SSLEEP; c = 'S'; break; 3102 case TS_RUN: state = SRUN; c = 'R'; break; 3103 case TS_ONPROC: state = SONPROC; c = 'O'; break; 3104 case TS_ZOMB: state = SZOMB; c = 'Z'; break; 3105 case TS_STOPPED: state = SSTOP; c = 'T'; break; 3106 case TS_WAIT: state = SWAIT; c = 'W'; break; 3107 default: state = 0; c = '?'; break; 3108 } 3109 psp->pr_state = state; 3110 psp->pr_sname = c; 3111 if ((sobj = t->t_sobj_ops) != NULL) 3112 psp->pr_stype = SOBJ_TYPE(sobj); 3113 retval = CL_DONICE(t, NULL, 0, &niceval); 3114 if (retval == 0) { 3115 psp->pr_oldpri = v.v_maxsyspri - t->t_pri; 3116 psp->pr_nice = niceval + NZERO; 3117 } 3118 psp->pr_syscall = t->t_sysnum; 3119 psp->pr_pri = t->t_pri; 3120 psp->pr_start.tv_sec = t->t_start; 3121 psp->pr_start.tv_nsec = 0L; 3122 hrutime = lwp->lwp_mstate.ms_acct[LMS_USER]; 3123 scalehrtime(&hrutime); 3124 hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] + 3125 lwp->lwp_mstate.ms_acct[LMS_TRAP]; 3126 scalehrtime(&hrstime); 3127 hrt2ts(hrutime + hrstime, &psp->pr_time); 3128 /* compute %cpu for the lwp */ 3129 pct = cpu_update_pct(t, gethrtime_unscaled()); 3130 psp->pr_pctcpu = prgetpctcpu(pct); 3131 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */ 3132 if (psp->pr_cpu > 99) 3133 psp->pr_cpu = 99; 3134 3135 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name, 3136 sizeof (psp->pr_clname) - 1); 3137 bzero(psp->pr_name, sizeof (psp->pr_name)); /* XXX ??? */ 3138 psp->pr_onpro = t->t_cpu->cpu_id; 3139 psp->pr_bindpro = t->t_bind_cpu; 3140 psp->pr_bindpset = t->t_bind_pset; 3141 psp->pr_lgrp = t->t_lpl->lpl_lgrpid; 3142 } 3143 3144 #ifdef _SYSCALL32_IMPL 3145 void 3146 prgetlwpsinfo32(kthread_t *t, lwpsinfo32_t *psp) 3147 { 3148 proc_t *p = ttoproc(t); 3149 klwp_t *lwp = ttolwp(t); 3150 sobj_ops_t *sobj; 3151 char c, state; 3152 uint64_t pct; 3153 int retval, niceval; 3154 hrtime_t hrutime, hrstime; 3155 3156 ASSERT(MUTEX_HELD(&p->p_lock)); 3157 3158 bzero(psp, sizeof (*psp)); 3159 3160 psp->pr_flag = 0; /* lwpsinfo_t.pr_flag is deprecated */ 3161 psp->pr_lwpid = t->t_tid; 3162 psp->pr_addr = 0; /* cannot represent 64-bit addr in 32 bits */ 3163 psp->pr_wchan = 0; /* cannot represent 64-bit addr in 32 bits */ 3164 3165 /* map the thread state enum into a process state enum */ 3166 state = VSTOPPED(t) ? TS_STOPPED : t->t_state; 3167 switch (state) { 3168 case TS_SLEEP: state = SSLEEP; c = 'S'; break; 3169 case TS_RUN: state = SRUN; c = 'R'; break; 3170 case TS_ONPROC: state = SONPROC; c = 'O'; break; 3171 case TS_ZOMB: state = SZOMB; c = 'Z'; break; 3172 case TS_STOPPED: state = SSTOP; c = 'T'; break; 3173 case TS_WAIT: state = SWAIT; c = 'W'; break; 3174 default: state = 0; c = '?'; break; 3175 } 3176 psp->pr_state = state; 3177 psp->pr_sname = c; 3178 if ((sobj = t->t_sobj_ops) != NULL) 3179 psp->pr_stype = SOBJ_TYPE(sobj); 3180 retval = CL_DONICE(t, NULL, 0, &niceval); 3181 if (retval == 0) { 3182 psp->pr_oldpri = v.v_maxsyspri - t->t_pri; 3183 psp->pr_nice = niceval + NZERO; 3184 } else { 3185 psp->pr_oldpri = 0; 3186 psp->pr_nice = 0; 3187 } 3188 psp->pr_syscall = t->t_sysnum; 3189 psp->pr_pri = t->t_pri; 3190 psp->pr_start.tv_sec = (time32_t)t->t_start; 3191 psp->pr_start.tv_nsec = 0L; 3192 hrutime = lwp->lwp_mstate.ms_acct[LMS_USER]; 3193 scalehrtime(&hrutime); 3194 hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] + 3195 lwp->lwp_mstate.ms_acct[LMS_TRAP]; 3196 scalehrtime(&hrstime); 3197 hrt2ts32(hrutime + hrstime, &psp->pr_time); 3198 /* compute %cpu for the lwp */ 3199 pct = cpu_update_pct(t, gethrtime_unscaled()); 3200 psp->pr_pctcpu = prgetpctcpu(pct); 3201 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */ 3202 if (psp->pr_cpu > 99) 3203 psp->pr_cpu = 99; 3204 3205 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name, 3206 sizeof (psp->pr_clname) - 1); 3207 bzero(psp->pr_name, sizeof (psp->pr_name)); /* XXX ??? */ 3208 psp->pr_onpro = t->t_cpu->cpu_id; 3209 psp->pr_bindpro = t->t_bind_cpu; 3210 psp->pr_bindpset = t->t_bind_pset; 3211 psp->pr_lgrp = t->t_lpl->lpl_lgrpid; 3212 } 3213 #endif /* _SYSCALL32_IMPL */ 3214 3215 #ifdef _SYSCALL32_IMPL 3216 3217 #define PR_COPY_FIELD(s, d, field) d->field = s->field 3218 3219 #define PR_COPY_FIELD_ILP32(s, d, field) \ 3220 if (s->pr_dmodel == PR_MODEL_ILP32) { \ 3221 d->field = s->field; \ 3222 } 3223 3224 #define PR_COPY_TIMESPEC(s, d, field) \ 3225 TIMESPEC_TO_TIMESPEC32(&d->field, &s->field); 3226 3227 #define PR_COPY_BUF(s, d, field) \ 3228 bcopy(s->field, d->field, sizeof (d->field)); 3229 3230 #define PR_IGNORE_FIELD(s, d, field) 3231 3232 void 3233 lwpsinfo_kto32(const struct lwpsinfo *src, struct lwpsinfo32 *dest) 3234 { 3235 bzero(dest, sizeof (*dest)); 3236 3237 PR_COPY_FIELD(src, dest, pr_flag); 3238 PR_COPY_FIELD(src, dest, pr_lwpid); 3239 PR_IGNORE_FIELD(src, dest, pr_addr); 3240 PR_IGNORE_FIELD(src, dest, pr_wchan); 3241 PR_COPY_FIELD(src, dest, pr_stype); 3242 PR_COPY_FIELD(src, dest, pr_state); 3243 PR_COPY_FIELD(src, dest, pr_sname); 3244 PR_COPY_FIELD(src, dest, pr_nice); 3245 PR_COPY_FIELD(src, dest, pr_syscall); 3246 PR_COPY_FIELD(src, dest, pr_oldpri); 3247 PR_COPY_FIELD(src, dest, pr_cpu); 3248 PR_COPY_FIELD(src, dest, pr_pri); 3249 PR_COPY_FIELD(src, dest, pr_pctcpu); 3250 PR_COPY_TIMESPEC(src, dest, pr_start); 3251 PR_COPY_BUF(src, dest, pr_clname); 3252 PR_COPY_BUF(src, dest, pr_name); 3253 PR_COPY_FIELD(src, dest, pr_onpro); 3254 PR_COPY_FIELD(src, dest, pr_bindpro); 3255 PR_COPY_FIELD(src, dest, pr_bindpset); 3256 PR_COPY_FIELD(src, dest, pr_lgrp); 3257 } 3258 3259 void 3260 psinfo_kto32(const struct psinfo *src, struct psinfo32 *dest) 3261 { 3262 bzero(dest, sizeof (*dest)); 3263 3264 PR_COPY_FIELD(src, dest, pr_flag); 3265 PR_COPY_FIELD(src, dest, pr_nlwp); 3266 PR_COPY_FIELD(src, dest, pr_pid); 3267 PR_COPY_FIELD(src, dest, pr_ppid); 3268 PR_COPY_FIELD(src, dest, pr_pgid); 3269 PR_COPY_FIELD(src, dest, pr_sid); 3270 PR_COPY_FIELD(src, dest, pr_uid); 3271 PR_COPY_FIELD(src, dest, pr_euid); 3272 PR_COPY_FIELD(src, dest, pr_gid); 3273 PR_COPY_FIELD(src, dest, pr_egid); 3274 PR_IGNORE_FIELD(src, dest, pr_addr); 3275 PR_COPY_FIELD_ILP32(src, dest, pr_size); 3276 PR_COPY_FIELD_ILP32(src, dest, pr_rssize); 3277 PR_COPY_FIELD(src, dest, pr_ttydev); 3278 PR_COPY_FIELD(src, dest, pr_pctcpu); 3279 PR_COPY_FIELD(src, dest, pr_pctmem); 3280 PR_COPY_TIMESPEC(src, dest, pr_start); 3281 PR_COPY_TIMESPEC(src, dest, pr_time); 3282 PR_COPY_TIMESPEC(src, dest, pr_ctime); 3283 PR_COPY_BUF(src, dest, pr_fname); 3284 PR_COPY_BUF(src, dest, pr_psargs); 3285 PR_COPY_FIELD(src, dest, pr_wstat); 3286 PR_COPY_FIELD(src, dest, pr_argc); 3287 PR_COPY_FIELD_ILP32(src, dest, pr_argv); 3288 PR_COPY_FIELD_ILP32(src, dest, pr_envp); 3289 PR_COPY_FIELD(src, dest, pr_dmodel); 3290 PR_COPY_FIELD(src, dest, pr_taskid); 3291 PR_COPY_FIELD(src, dest, pr_projid); 3292 PR_COPY_FIELD(src, dest, pr_nzomb); 3293 PR_COPY_FIELD(src, dest, pr_poolid); 3294 PR_COPY_FIELD(src, dest, pr_contract); 3295 PR_COPY_FIELD(src, dest, pr_poolid); 3296 PR_COPY_FIELD(src, dest, pr_poolid); 3297 3298 lwpsinfo_kto32(&src->pr_lwp, &dest->pr_lwp); 3299 } 3300 3301 #undef PR_COPY_FIELD 3302 #undef PR_COPY_FIELD_ILP32 3303 #undef PR_COPY_TIMESPEC 3304 #undef PR_COPY_BUF 3305 #undef PR_IGNORE_FIELD 3306 3307 #endif /* _SYSCALL32_IMPL */ 3308 3309 /* 3310 * This used to get called when microstate accounting was disabled but 3311 * microstate information was requested. Since Microstate accounting is on 3312 * regardless of the proc flags, this simply makes it appear to procfs that 3313 * microstate accounting is on. This is relatively meaningless since you 3314 * can't turn it off, but this is here for the sake of appearances. 3315 */ 3316 3317 /*ARGSUSED*/ 3318 void 3319 estimate_msacct(kthread_t *t, hrtime_t curtime) 3320 { 3321 proc_t *p; 3322 3323 if (t == NULL) 3324 return; 3325 3326 p = ttoproc(t); 3327 ASSERT(MUTEX_HELD(&p->p_lock)); 3328 3329 /* 3330 * A system process (p0) could be referenced if the thread is 3331 * in the process of exiting. Don't turn on microstate accounting 3332 * in that case. 3333 */ 3334 if (p->p_flag & SSYS) 3335 return; 3336 3337 /* 3338 * Loop through all the LWPs (kernel threads) in the process. 3339 */ 3340 t = p->p_tlist; 3341 do { 3342 t->t_proc_flag |= TP_MSACCT; 3343 } while ((t = t->t_forw) != p->p_tlist); 3344 3345 p->p_flag |= SMSACCT; /* set process-wide MSACCT */ 3346 } 3347 3348 /* 3349 * It's not really possible to disable microstate accounting anymore. 3350 * However, this routine simply turns off the ms accounting flags in a process 3351 * This way procfs can still pretend to turn microstate accounting on and 3352 * off for a process, but it actually doesn't do anything. This is 3353 * a neutered form of preemptive idiot-proofing. 3354 */ 3355 void 3356 disable_msacct(proc_t *p) 3357 { 3358 kthread_t *t; 3359 3360 ASSERT(MUTEX_HELD(&p->p_lock)); 3361 3362 p->p_flag &= ~SMSACCT; /* clear process-wide MSACCT */ 3363 /* 3364 * Loop through all the LWPs (kernel threads) in the process. 3365 */ 3366 if ((t = p->p_tlist) != NULL) { 3367 do { 3368 /* clear per-thread flag */ 3369 t->t_proc_flag &= ~TP_MSACCT; 3370 } while ((t = t->t_forw) != p->p_tlist); 3371 } 3372 } 3373 3374 /* 3375 * Return resource usage information. 3376 */ 3377 void 3378 prgetusage(kthread_t *t, prhusage_t *pup) 3379 { 3380 klwp_t *lwp = ttolwp(t); 3381 hrtime_t *mstimep; 3382 struct mstate *ms = &lwp->lwp_mstate; 3383 int state; 3384 int i; 3385 hrtime_t curtime; 3386 hrtime_t waitrq; 3387 hrtime_t tmp1; 3388 3389 curtime = gethrtime_unscaled(); 3390 3391 pup->pr_lwpid = t->t_tid; 3392 pup->pr_count = 1; 3393 pup->pr_create = ms->ms_start; 3394 pup->pr_term = ms->ms_term; 3395 scalehrtime(&pup->pr_create); 3396 scalehrtime(&pup->pr_term); 3397 if (ms->ms_term == 0) { 3398 pup->pr_rtime = curtime - ms->ms_start; 3399 scalehrtime(&pup->pr_rtime); 3400 } else { 3401 pup->pr_rtime = ms->ms_term - ms->ms_start; 3402 scalehrtime(&pup->pr_rtime); 3403 } 3404 3405 3406 pup->pr_utime = ms->ms_acct[LMS_USER]; 3407 pup->pr_stime = ms->ms_acct[LMS_SYSTEM]; 3408 pup->pr_ttime = ms->ms_acct[LMS_TRAP]; 3409 pup->pr_tftime = ms->ms_acct[LMS_TFAULT]; 3410 pup->pr_dftime = ms->ms_acct[LMS_DFAULT]; 3411 pup->pr_kftime = ms->ms_acct[LMS_KFAULT]; 3412 pup->pr_ltime = ms->ms_acct[LMS_USER_LOCK]; 3413 pup->pr_slptime = ms->ms_acct[LMS_SLEEP]; 3414 pup->pr_wtime = ms->ms_acct[LMS_WAIT_CPU]; 3415 pup->pr_stoptime = ms->ms_acct[LMS_STOPPED]; 3416 3417 prscaleusage(pup); 3418 3419 /* 3420 * Adjust for time waiting in the dispatcher queue. 3421 */ 3422 waitrq = t->t_waitrq; /* hopefully atomic */ 3423 if (waitrq != 0) { 3424 if (waitrq > curtime) { 3425 curtime = gethrtime_unscaled(); 3426 } 3427 tmp1 = curtime - waitrq; 3428 scalehrtime(&tmp1); 3429 pup->pr_wtime += tmp1; 3430 curtime = waitrq; 3431 } 3432 3433 /* 3434 * Adjust for time spent in current microstate. 3435 */ 3436 if (ms->ms_state_start > curtime) { 3437 curtime = gethrtime_unscaled(); 3438 } 3439 3440 i = 0; 3441 do { 3442 switch (state = t->t_mstate) { 3443 case LMS_SLEEP: 3444 /* 3445 * Update the timer for the current sleep state. 3446 */ 3447 switch (state = ms->ms_prev) { 3448 case LMS_TFAULT: 3449 case LMS_DFAULT: 3450 case LMS_KFAULT: 3451 case LMS_USER_LOCK: 3452 break; 3453 default: 3454 state = LMS_SLEEP; 3455 break; 3456 } 3457 break; 3458 case LMS_TFAULT: 3459 case LMS_DFAULT: 3460 case LMS_KFAULT: 3461 case LMS_USER_LOCK: 3462 state = LMS_SYSTEM; 3463 break; 3464 } 3465 switch (state) { 3466 case LMS_USER: mstimep = &pup->pr_utime; break; 3467 case LMS_SYSTEM: mstimep = &pup->pr_stime; break; 3468 case LMS_TRAP: mstimep = &pup->pr_ttime; break; 3469 case LMS_TFAULT: mstimep = &pup->pr_tftime; break; 3470 case LMS_DFAULT: mstimep = &pup->pr_dftime; break; 3471 case LMS_KFAULT: mstimep = &pup->pr_kftime; break; 3472 case LMS_USER_LOCK: mstimep = &pup->pr_ltime; break; 3473 case LMS_SLEEP: mstimep = &pup->pr_slptime; break; 3474 case LMS_WAIT_CPU: mstimep = &pup->pr_wtime; break; 3475 case LMS_STOPPED: mstimep = &pup->pr_stoptime; break; 3476 default: panic("prgetusage: unknown microstate"); 3477 } 3478 tmp1 = curtime - ms->ms_state_start; 3479 if (tmp1 < 0) { 3480 curtime = gethrtime_unscaled(); 3481 i++; 3482 continue; 3483 } 3484 scalehrtime(&tmp1); 3485 } while (tmp1 < 0 && i < MAX_ITERS_SPIN); 3486 3487 *mstimep += tmp1; 3488 3489 /* update pup timestamp */ 3490 pup->pr_tstamp = curtime; 3491 scalehrtime(&pup->pr_tstamp); 3492 3493 /* 3494 * Resource usage counters. 3495 */ 3496 pup->pr_minf = lwp->lwp_ru.minflt; 3497 pup->pr_majf = lwp->lwp_ru.majflt; 3498 pup->pr_nswap = lwp->lwp_ru.nswap; 3499 pup->pr_inblk = lwp->lwp_ru.inblock; 3500 pup->pr_oublk = lwp->lwp_ru.oublock; 3501 pup->pr_msnd = lwp->lwp_ru.msgsnd; 3502 pup->pr_mrcv = lwp->lwp_ru.msgrcv; 3503 pup->pr_sigs = lwp->lwp_ru.nsignals; 3504 pup->pr_vctx = lwp->lwp_ru.nvcsw; 3505 pup->pr_ictx = lwp->lwp_ru.nivcsw; 3506 pup->pr_sysc = lwp->lwp_ru.sysc; 3507 pup->pr_ioch = lwp->lwp_ru.ioch; 3508 } 3509 3510 /* 3511 * Convert ms_acct stats from unscaled high-res time to nanoseconds 3512 */ 3513 void 3514 prscaleusage(prhusage_t *usg) 3515 { 3516 scalehrtime(&usg->pr_utime); 3517 scalehrtime(&usg->pr_stime); 3518 scalehrtime(&usg->pr_ttime); 3519 scalehrtime(&usg->pr_tftime); 3520 scalehrtime(&usg->pr_dftime); 3521 scalehrtime(&usg->pr_kftime); 3522 scalehrtime(&usg->pr_ltime); 3523 scalehrtime(&usg->pr_slptime); 3524 scalehrtime(&usg->pr_wtime); 3525 scalehrtime(&usg->pr_stoptime); 3526 } 3527 3528 3529 /* 3530 * Sum resource usage information. 3531 */ 3532 void 3533 praddusage(kthread_t *t, prhusage_t *pup) 3534 { 3535 klwp_t *lwp = ttolwp(t); 3536 hrtime_t *mstimep; 3537 struct mstate *ms = &lwp->lwp_mstate; 3538 int state; 3539 int i; 3540 hrtime_t curtime; 3541 hrtime_t waitrq; 3542 hrtime_t tmp; 3543 prhusage_t conv; 3544 3545 curtime = gethrtime_unscaled(); 3546 3547 if (ms->ms_term == 0) { 3548 tmp = curtime - ms->ms_start; 3549 scalehrtime(&tmp); 3550 pup->pr_rtime += tmp; 3551 } else { 3552 tmp = ms->ms_term - ms->ms_start; 3553 scalehrtime(&tmp); 3554 pup->pr_rtime += tmp; 3555 } 3556 3557 conv.pr_utime = ms->ms_acct[LMS_USER]; 3558 conv.pr_stime = ms->ms_acct[LMS_SYSTEM]; 3559 conv.pr_ttime = ms->ms_acct[LMS_TRAP]; 3560 conv.pr_tftime = ms->ms_acct[LMS_TFAULT]; 3561 conv.pr_dftime = ms->ms_acct[LMS_DFAULT]; 3562 conv.pr_kftime = ms->ms_acct[LMS_KFAULT]; 3563 conv.pr_ltime = ms->ms_acct[LMS_USER_LOCK]; 3564 conv.pr_slptime = ms->ms_acct[LMS_SLEEP]; 3565 conv.pr_wtime = ms->ms_acct[LMS_WAIT_CPU]; 3566 conv.pr_stoptime = ms->ms_acct[LMS_STOPPED]; 3567 3568 prscaleusage(&conv); 3569 3570 pup->pr_utime += conv.pr_utime; 3571 pup->pr_stime += conv.pr_stime; 3572 pup->pr_ttime += conv.pr_ttime; 3573 pup->pr_tftime += conv.pr_tftime; 3574 pup->pr_dftime += conv.pr_dftime; 3575 pup->pr_kftime += conv.pr_kftime; 3576 pup->pr_ltime += conv.pr_ltime; 3577 pup->pr_slptime += conv.pr_slptime; 3578 pup->pr_wtime += conv.pr_wtime; 3579 pup->pr_stoptime += conv.pr_stoptime; 3580 3581 /* 3582 * Adjust for time waiting in the dispatcher queue. 3583 */ 3584 waitrq = t->t_waitrq; /* hopefully atomic */ 3585 if (waitrq != 0) { 3586 if (waitrq > curtime) { 3587 curtime = gethrtime_unscaled(); 3588 } 3589 tmp = curtime - waitrq; 3590 scalehrtime(&tmp); 3591 pup->pr_wtime += tmp; 3592 curtime = waitrq; 3593 } 3594 3595 /* 3596 * Adjust for time spent in current microstate. 3597 */ 3598 if (ms->ms_state_start > curtime) { 3599 curtime = gethrtime_unscaled(); 3600 } 3601 3602 i = 0; 3603 do { 3604 switch (state = t->t_mstate) { 3605 case LMS_SLEEP: 3606 /* 3607 * Update the timer for the current sleep state. 3608 */ 3609 switch (state = ms->ms_prev) { 3610 case LMS_TFAULT: 3611 case LMS_DFAULT: 3612 case LMS_KFAULT: 3613 case LMS_USER_LOCK: 3614 break; 3615 default: 3616 state = LMS_SLEEP; 3617 break; 3618 } 3619 break; 3620 case LMS_TFAULT: 3621 case LMS_DFAULT: 3622 case LMS_KFAULT: 3623 case LMS_USER_LOCK: 3624 state = LMS_SYSTEM; 3625 break; 3626 } 3627 switch (state) { 3628 case LMS_USER: mstimep = &pup->pr_utime; break; 3629 case LMS_SYSTEM: mstimep = &pup->pr_stime; break; 3630 case LMS_TRAP: mstimep = &pup->pr_ttime; break; 3631 case LMS_TFAULT: mstimep = &pup->pr_tftime; break; 3632 case LMS_DFAULT: mstimep = &pup->pr_dftime; break; 3633 case LMS_KFAULT: mstimep = &pup->pr_kftime; break; 3634 case LMS_USER_LOCK: mstimep = &pup->pr_ltime; break; 3635 case LMS_SLEEP: mstimep = &pup->pr_slptime; break; 3636 case LMS_WAIT_CPU: mstimep = &pup->pr_wtime; break; 3637 case LMS_STOPPED: mstimep = &pup->pr_stoptime; break; 3638 default: panic("praddusage: unknown microstate"); 3639 } 3640 tmp = curtime - ms->ms_state_start; 3641 if (tmp < 0) { 3642 curtime = gethrtime_unscaled(); 3643 i++; 3644 continue; 3645 } 3646 scalehrtime(&tmp); 3647 } while (tmp < 0 && i < MAX_ITERS_SPIN); 3648 3649 *mstimep += tmp; 3650 3651 /* update pup timestamp */ 3652 pup->pr_tstamp = curtime; 3653 scalehrtime(&pup->pr_tstamp); 3654 3655 /* 3656 * Resource usage counters. 3657 */ 3658 pup->pr_minf += lwp->lwp_ru.minflt; 3659 pup->pr_majf += lwp->lwp_ru.majflt; 3660 pup->pr_nswap += lwp->lwp_ru.nswap; 3661 pup->pr_inblk += lwp->lwp_ru.inblock; 3662 pup->pr_oublk += lwp->lwp_ru.oublock; 3663 pup->pr_msnd += lwp->lwp_ru.msgsnd; 3664 pup->pr_mrcv += lwp->lwp_ru.msgrcv; 3665 pup->pr_sigs += lwp->lwp_ru.nsignals; 3666 pup->pr_vctx += lwp->lwp_ru.nvcsw; 3667 pup->pr_ictx += lwp->lwp_ru.nivcsw; 3668 pup->pr_sysc += lwp->lwp_ru.sysc; 3669 pup->pr_ioch += lwp->lwp_ru.ioch; 3670 } 3671 3672 /* 3673 * Convert a prhusage_t to a prusage_t. 3674 * This means convert each hrtime_t to a timestruc_t 3675 * and copy the count fields uint64_t => ulong_t. 3676 */ 3677 void 3678 prcvtusage(prhusage_t *pup, prusage_t *upup) 3679 { 3680 uint64_t *ullp; 3681 ulong_t *ulp; 3682 int i; 3683 3684 upup->pr_lwpid = pup->pr_lwpid; 3685 upup->pr_count = pup->pr_count; 3686 3687 hrt2ts(pup->pr_tstamp, &upup->pr_tstamp); 3688 hrt2ts(pup->pr_create, &upup->pr_create); 3689 hrt2ts(pup->pr_term, &upup->pr_term); 3690 hrt2ts(pup->pr_rtime, &upup->pr_rtime); 3691 hrt2ts(pup->pr_utime, &upup->pr_utime); 3692 hrt2ts(pup->pr_stime, &upup->pr_stime); 3693 hrt2ts(pup->pr_ttime, &upup->pr_ttime); 3694 hrt2ts(pup->pr_tftime, &upup->pr_tftime); 3695 hrt2ts(pup->pr_dftime, &upup->pr_dftime); 3696 hrt2ts(pup->pr_kftime, &upup->pr_kftime); 3697 hrt2ts(pup->pr_ltime, &upup->pr_ltime); 3698 hrt2ts(pup->pr_slptime, &upup->pr_slptime); 3699 hrt2ts(pup->pr_wtime, &upup->pr_wtime); 3700 hrt2ts(pup->pr_stoptime, &upup->pr_stoptime); 3701 bzero(upup->filltime, sizeof (upup->filltime)); 3702 3703 ullp = &pup->pr_minf; 3704 ulp = &upup->pr_minf; 3705 for (i = 0; i < 22; i++) 3706 *ulp++ = (ulong_t)*ullp++; 3707 } 3708 3709 #ifdef _SYSCALL32_IMPL 3710 void 3711 prcvtusage32(prhusage_t *pup, prusage32_t *upup) 3712 { 3713 uint64_t *ullp; 3714 uint32_t *ulp; 3715 int i; 3716 3717 upup->pr_lwpid = pup->pr_lwpid; 3718 upup->pr_count = pup->pr_count; 3719 3720 hrt2ts32(pup->pr_tstamp, &upup->pr_tstamp); 3721 hrt2ts32(pup->pr_create, &upup->pr_create); 3722 hrt2ts32(pup->pr_term, &upup->pr_term); 3723 hrt2ts32(pup->pr_rtime, &upup->pr_rtime); 3724 hrt2ts32(pup->pr_utime, &upup->pr_utime); 3725 hrt2ts32(pup->pr_stime, &upup->pr_stime); 3726 hrt2ts32(pup->pr_ttime, &upup->pr_ttime); 3727 hrt2ts32(pup->pr_tftime, &upup->pr_tftime); 3728 hrt2ts32(pup->pr_dftime, &upup->pr_dftime); 3729 hrt2ts32(pup->pr_kftime, &upup->pr_kftime); 3730 hrt2ts32(pup->pr_ltime, &upup->pr_ltime); 3731 hrt2ts32(pup->pr_slptime, &upup->pr_slptime); 3732 hrt2ts32(pup->pr_wtime, &upup->pr_wtime); 3733 hrt2ts32(pup->pr_stoptime, &upup->pr_stoptime); 3734 bzero(upup->filltime, sizeof (upup->filltime)); 3735 3736 ullp = &pup->pr_minf; 3737 ulp = &upup->pr_minf; 3738 for (i = 0; i < 22; i++) 3739 *ulp++ = (uint32_t)*ullp++; 3740 } 3741 #endif /* _SYSCALL32_IMPL */ 3742 3743 /* 3744 * Determine whether a set is empty. 3745 */ 3746 int 3747 setisempty(uint32_t *sp, uint_t n) 3748 { 3749 while (n--) 3750 if (*sp++) 3751 return (0); 3752 return (1); 3753 } 3754 3755 /* 3756 * Utility routine for establishing a watched area in the process. 3757 * Keep the list of watched areas sorted by virtual address. 3758 */ 3759 int 3760 set_watched_area(proc_t *p, struct watched_area *pwa) 3761 { 3762 caddr_t vaddr = pwa->wa_vaddr; 3763 caddr_t eaddr = pwa->wa_eaddr; 3764 ulong_t flags = pwa->wa_flags; 3765 struct watched_area *target; 3766 avl_index_t where; 3767 int error = 0; 3768 3769 /* we must not be holding p->p_lock, but the process must be locked */ 3770 ASSERT(MUTEX_NOT_HELD(&p->p_lock)); 3771 ASSERT(p->p_proc_flag & P_PR_LOCK); 3772 3773 /* 3774 * If this is our first watchpoint, enable watchpoints for the process. 3775 */ 3776 if (!pr_watch_active(p)) { 3777 kthread_t *t; 3778 3779 mutex_enter(&p->p_lock); 3780 if ((t = p->p_tlist) != NULL) { 3781 do { 3782 watch_enable(t); 3783 } while ((t = t->t_forw) != p->p_tlist); 3784 } 3785 mutex_exit(&p->p_lock); 3786 } 3787 3788 target = pr_find_watched_area(p, pwa, &where); 3789 if (target != NULL) { 3790 /* 3791 * We discovered an existing, overlapping watched area. 3792 * Allow it only if it is an exact match. 3793 */ 3794 if (target->wa_vaddr != vaddr || 3795 target->wa_eaddr != eaddr) 3796 error = EINVAL; 3797 else if (target->wa_flags != flags) { 3798 error = set_watched_page(p, vaddr, eaddr, 3799 flags, target->wa_flags); 3800 target->wa_flags = flags; 3801 } 3802 kmem_free(pwa, sizeof (struct watched_area)); 3803 } else { 3804 avl_insert(&p->p_warea, pwa, where); 3805 error = set_watched_page(p, vaddr, eaddr, flags, 0); 3806 } 3807 3808 return (error); 3809 } 3810 3811 /* 3812 * Utility routine for clearing a watched area in the process. 3813 * Must be an exact match of the virtual address. 3814 * size and flags don't matter. 3815 */ 3816 int 3817 clear_watched_area(proc_t *p, struct watched_area *pwa) 3818 { 3819 struct watched_area *found; 3820 3821 /* we must not be holding p->p_lock, but the process must be locked */ 3822 ASSERT(MUTEX_NOT_HELD(&p->p_lock)); 3823 ASSERT(p->p_proc_flag & P_PR_LOCK); 3824 3825 3826 if (!pr_watch_active(p)) { 3827 kmem_free(pwa, sizeof (struct watched_area)); 3828 return (0); 3829 } 3830 3831 /* 3832 * Look for a matching address in the watched areas. If a match is 3833 * found, clear the old watched area and adjust the watched page(s). It 3834 * is not an error if there is no match. 3835 */ 3836 if ((found = pr_find_watched_area(p, pwa, NULL)) != NULL && 3837 found->wa_vaddr == pwa->wa_vaddr) { 3838 clear_watched_page(p, found->wa_vaddr, found->wa_eaddr, 3839 found->wa_flags); 3840 avl_remove(&p->p_warea, found); 3841 kmem_free(found, sizeof (struct watched_area)); 3842 } 3843 3844 kmem_free(pwa, sizeof (struct watched_area)); 3845 3846 /* 3847 * If we removed the last watched area from the process, disable 3848 * watchpoints. 3849 */ 3850 if (!pr_watch_active(p)) { 3851 kthread_t *t; 3852 3853 mutex_enter(&p->p_lock); 3854 if ((t = p->p_tlist) != NULL) { 3855 do { 3856 watch_disable(t); 3857 } while ((t = t->t_forw) != p->p_tlist); 3858 } 3859 mutex_exit(&p->p_lock); 3860 } 3861 3862 return (0); 3863 } 3864 3865 /* 3866 * Frees all the watched_area structures 3867 */ 3868 void 3869 pr_free_watchpoints(proc_t *p) 3870 { 3871 struct watched_area *delp; 3872 void *cookie; 3873 3874 cookie = NULL; 3875 while ((delp = avl_destroy_nodes(&p->p_warea, &cookie)) != NULL) 3876 kmem_free(delp, sizeof (struct watched_area)); 3877 3878 avl_destroy(&p->p_warea); 3879 } 3880 3881 /* 3882 * This one is called by the traced process to unwatch all the 3883 * pages while deallocating the list of watched_page structs. 3884 */ 3885 void 3886 pr_free_watched_pages(proc_t *p) 3887 { 3888 struct as *as = p->p_as; 3889 struct watched_page *pwp; 3890 uint_t prot; 3891 int retrycnt, err; 3892 void *cookie; 3893 3894 if (as == NULL || avl_numnodes(&as->a_wpage) == 0) 3895 return; 3896 3897 ASSERT(MUTEX_NOT_HELD(&curproc->p_lock)); 3898 AS_LOCK_ENTER(as, RW_WRITER); 3899 3900 pwp = avl_first(&as->a_wpage); 3901 3902 cookie = NULL; 3903 while ((pwp = avl_destroy_nodes(&as->a_wpage, &cookie)) != NULL) { 3904 retrycnt = 0; 3905 if ((prot = pwp->wp_oprot) != 0) { 3906 caddr_t addr = pwp->wp_vaddr; 3907 struct seg *seg; 3908 retry: 3909 3910 if ((pwp->wp_prot != prot || 3911 (pwp->wp_flags & WP_NOWATCH)) && 3912 (seg = as_segat(as, addr)) != NULL) { 3913 err = SEGOP_SETPROT(seg, addr, PAGESIZE, prot); 3914 if (err == IE_RETRY) { 3915 ASSERT(retrycnt == 0); 3916 retrycnt++; 3917 goto retry; 3918 } 3919 } 3920 } 3921 kmem_free(pwp, sizeof (struct watched_page)); 3922 } 3923 3924 avl_destroy(&as->a_wpage); 3925 p->p_wprot = NULL; 3926 3927 AS_LOCK_EXIT(as); 3928 } 3929 3930 /* 3931 * Insert a watched area into the list of watched pages. 3932 * If oflags is zero then we are adding a new watched area. 3933 * Otherwise we are changing the flags of an existing watched area. 3934 */ 3935 static int 3936 set_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr, 3937 ulong_t flags, ulong_t oflags) 3938 { 3939 struct as *as = p->p_as; 3940 avl_tree_t *pwp_tree; 3941 struct watched_page *pwp, *newpwp; 3942 struct watched_page tpw; 3943 avl_index_t where; 3944 struct seg *seg; 3945 uint_t prot; 3946 caddr_t addr; 3947 3948 /* 3949 * We need to pre-allocate a list of structures before we grab the 3950 * address space lock to avoid calling kmem_alloc(KM_SLEEP) with locks 3951 * held. 3952 */ 3953 newpwp = NULL; 3954 for (addr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK); 3955 addr < eaddr; addr += PAGESIZE) { 3956 pwp = kmem_zalloc(sizeof (struct watched_page), KM_SLEEP); 3957 pwp->wp_list = newpwp; 3958 newpwp = pwp; 3959 } 3960 3961 AS_LOCK_ENTER(as, RW_WRITER); 3962 3963 /* 3964 * Search for an existing watched page to contain the watched area. 3965 * If none is found, grab a new one from the available list 3966 * and insert it in the active list, keeping the list sorted 3967 * by user-level virtual address. 3968 */ 3969 if (p->p_flag & SVFWAIT) 3970 pwp_tree = &p->p_wpage; 3971 else 3972 pwp_tree = &as->a_wpage; 3973 3974 again: 3975 if (avl_numnodes(pwp_tree) > prnwatch) { 3976 AS_LOCK_EXIT(as); 3977 while (newpwp != NULL) { 3978 pwp = newpwp->wp_list; 3979 kmem_free(newpwp, sizeof (struct watched_page)); 3980 newpwp = pwp; 3981 } 3982 return (E2BIG); 3983 } 3984 3985 tpw.wp_vaddr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK); 3986 if ((pwp = avl_find(pwp_tree, &tpw, &where)) == NULL) { 3987 pwp = newpwp; 3988 newpwp = newpwp->wp_list; 3989 pwp->wp_list = NULL; 3990 pwp->wp_vaddr = (caddr_t)((uintptr_t)vaddr & 3991 (uintptr_t)PAGEMASK); 3992 avl_insert(pwp_tree, pwp, where); 3993 } 3994 3995 ASSERT(vaddr >= pwp->wp_vaddr && vaddr < pwp->wp_vaddr + PAGESIZE); 3996 3997 if (oflags & WA_READ) 3998 pwp->wp_read--; 3999 if (oflags & WA_WRITE) 4000 pwp->wp_write--; 4001 if (oflags & WA_EXEC) 4002 pwp->wp_exec--; 4003 4004 ASSERT(pwp->wp_read >= 0); 4005 ASSERT(pwp->wp_write >= 0); 4006 ASSERT(pwp->wp_exec >= 0); 4007 4008 if (flags & WA_READ) 4009 pwp->wp_read++; 4010 if (flags & WA_WRITE) 4011 pwp->wp_write++; 4012 if (flags & WA_EXEC) 4013 pwp->wp_exec++; 4014 4015 if (!(p->p_flag & SVFWAIT)) { 4016 vaddr = pwp->wp_vaddr; 4017 if (pwp->wp_oprot == 0 && 4018 (seg = as_segat(as, vaddr)) != NULL) { 4019 SEGOP_GETPROT(seg, vaddr, 0, &prot); 4020 pwp->wp_oprot = (uchar_t)prot; 4021 pwp->wp_prot = (uchar_t)prot; 4022 } 4023 if (pwp->wp_oprot != 0) { 4024 prot = pwp->wp_oprot; 4025 if (pwp->wp_read) 4026 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC); 4027 if (pwp->wp_write) 4028 prot &= ~PROT_WRITE; 4029 if (pwp->wp_exec) 4030 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC); 4031 if (!(pwp->wp_flags & WP_NOWATCH) && 4032 pwp->wp_prot != prot && 4033 (pwp->wp_flags & WP_SETPROT) == 0) { 4034 pwp->wp_flags |= WP_SETPROT; 4035 pwp->wp_list = p->p_wprot; 4036 p->p_wprot = pwp; 4037 } 4038 pwp->wp_prot = (uchar_t)prot; 4039 } 4040 } 4041 4042 /* 4043 * If the watched area extends into the next page then do 4044 * it over again with the virtual address of the next page. 4045 */ 4046 if ((vaddr = pwp->wp_vaddr + PAGESIZE) < eaddr) 4047 goto again; 4048 4049 AS_LOCK_EXIT(as); 4050 4051 /* 4052 * Free any pages we may have over-allocated 4053 */ 4054 while (newpwp != NULL) { 4055 pwp = newpwp->wp_list; 4056 kmem_free(newpwp, sizeof (struct watched_page)); 4057 newpwp = pwp; 4058 } 4059 4060 return (0); 4061 } 4062 4063 /* 4064 * Remove a watched area from the list of watched pages. 4065 * A watched area may extend over more than one page. 4066 */ 4067 static void 4068 clear_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr, ulong_t flags) 4069 { 4070 struct as *as = p->p_as; 4071 struct watched_page *pwp; 4072 struct watched_page tpw; 4073 avl_tree_t *tree; 4074 avl_index_t where; 4075 4076 AS_LOCK_ENTER(as, RW_WRITER); 4077 4078 if (p->p_flag & SVFWAIT) 4079 tree = &p->p_wpage; 4080 else 4081 tree = &as->a_wpage; 4082 4083 tpw.wp_vaddr = vaddr = 4084 (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK); 4085 pwp = avl_find(tree, &tpw, &where); 4086 if (pwp == NULL) 4087 pwp = avl_nearest(tree, where, AVL_AFTER); 4088 4089 while (pwp != NULL && pwp->wp_vaddr < eaddr) { 4090 ASSERT(vaddr <= pwp->wp_vaddr); 4091 4092 if (flags & WA_READ) 4093 pwp->wp_read--; 4094 if (flags & WA_WRITE) 4095 pwp->wp_write--; 4096 if (flags & WA_EXEC) 4097 pwp->wp_exec--; 4098 4099 if (pwp->wp_read + pwp->wp_write + pwp->wp_exec != 0) { 4100 /* 4101 * Reset the hat layer's protections on this page. 4102 */ 4103 if (pwp->wp_oprot != 0) { 4104 uint_t prot = pwp->wp_oprot; 4105 4106 if (pwp->wp_read) 4107 prot &= 4108 ~(PROT_READ|PROT_WRITE|PROT_EXEC); 4109 if (pwp->wp_write) 4110 prot &= ~PROT_WRITE; 4111 if (pwp->wp_exec) 4112 prot &= 4113 ~(PROT_READ|PROT_WRITE|PROT_EXEC); 4114 if (!(pwp->wp_flags & WP_NOWATCH) && 4115 pwp->wp_prot != prot && 4116 (pwp->wp_flags & WP_SETPROT) == 0) { 4117 pwp->wp_flags |= WP_SETPROT; 4118 pwp->wp_list = p->p_wprot; 4119 p->p_wprot = pwp; 4120 } 4121 pwp->wp_prot = (uchar_t)prot; 4122 } 4123 } else { 4124 /* 4125 * No watched areas remain in this page. 4126 * Reset everything to normal. 4127 */ 4128 if (pwp->wp_oprot != 0) { 4129 pwp->wp_prot = pwp->wp_oprot; 4130 if ((pwp->wp_flags & WP_SETPROT) == 0) { 4131 pwp->wp_flags |= WP_SETPROT; 4132 pwp->wp_list = p->p_wprot; 4133 p->p_wprot = pwp; 4134 } 4135 } 4136 } 4137 4138 pwp = AVL_NEXT(tree, pwp); 4139 } 4140 4141 AS_LOCK_EXIT(as); 4142 } 4143 4144 /* 4145 * Return the original protections for the specified page. 4146 */ 4147 static void 4148 getwatchprot(struct as *as, caddr_t addr, uint_t *prot) 4149 { 4150 struct watched_page *pwp; 4151 struct watched_page tpw; 4152 4153 ASSERT(AS_LOCK_HELD(as)); 4154 4155 tpw.wp_vaddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK); 4156 if ((pwp = avl_find(&as->a_wpage, &tpw, NULL)) != NULL) 4157 *prot = pwp->wp_oprot; 4158 } 4159 4160 static prpagev_t * 4161 pr_pagev_create(struct seg *seg, int check_noreserve) 4162 { 4163 prpagev_t *pagev = kmem_alloc(sizeof (prpagev_t), KM_SLEEP); 4164 size_t total_pages = seg_pages(seg); 4165 4166 /* 4167 * Limit the size of our vectors to pagev_lim pages at a time. We need 4168 * 4 or 5 bytes of storage per page, so this means we limit ourself 4169 * to about a megabyte of kernel heap by default. 4170 */ 4171 pagev->pg_npages = MIN(total_pages, pagev_lim); 4172 pagev->pg_pnbase = 0; 4173 4174 pagev->pg_protv = 4175 kmem_alloc(pagev->pg_npages * sizeof (uint_t), KM_SLEEP); 4176 4177 if (check_noreserve) 4178 pagev->pg_incore = 4179 kmem_alloc(pagev->pg_npages * sizeof (char), KM_SLEEP); 4180 else 4181 pagev->pg_incore = NULL; 4182 4183 return (pagev); 4184 } 4185 4186 static void 4187 pr_pagev_destroy(prpagev_t *pagev) 4188 { 4189 if (pagev->pg_incore != NULL) 4190 kmem_free(pagev->pg_incore, pagev->pg_npages * sizeof (char)); 4191 4192 kmem_free(pagev->pg_protv, pagev->pg_npages * sizeof (uint_t)); 4193 kmem_free(pagev, sizeof (prpagev_t)); 4194 } 4195 4196 static caddr_t 4197 pr_pagev_fill(prpagev_t *pagev, struct seg *seg, caddr_t addr, caddr_t eaddr) 4198 { 4199 ulong_t lastpg = seg_page(seg, eaddr - 1); 4200 ulong_t pn, pnlim; 4201 caddr_t saddr; 4202 size_t len; 4203 4204 ASSERT(addr >= seg->s_base && addr <= eaddr); 4205 4206 if (addr == eaddr) 4207 return (eaddr); 4208 4209 refill: 4210 ASSERT(addr < eaddr); 4211 pagev->pg_pnbase = seg_page(seg, addr); 4212 pnlim = pagev->pg_pnbase + pagev->pg_npages; 4213 saddr = addr; 4214 4215 if (lastpg < pnlim) 4216 len = (size_t)(eaddr - addr); 4217 else 4218 len = pagev->pg_npages * PAGESIZE; 4219 4220 if (pagev->pg_incore != NULL) { 4221 /* 4222 * INCORE cleverly has different semantics than GETPROT: 4223 * it returns info on pages up to but NOT including addr + len. 4224 */ 4225 SEGOP_INCORE(seg, addr, len, pagev->pg_incore); 4226 pn = pagev->pg_pnbase; 4227 4228 do { 4229 /* 4230 * Guilty knowledge here: We know that segvn_incore 4231 * returns more than just the low-order bit that 4232 * indicates the page is actually in memory. If any 4233 * bits are set, then the page has backing store. 4234 */ 4235 if (pagev->pg_incore[pn++ - pagev->pg_pnbase]) 4236 goto out; 4237 4238 } while ((addr += PAGESIZE) < eaddr && pn < pnlim); 4239 4240 /* 4241 * If we examined all the pages in the vector but we're not 4242 * at the end of the segment, take another lap. 4243 */ 4244 if (addr < eaddr) 4245 goto refill; 4246 } 4247 4248 /* 4249 * Need to take len - 1 because addr + len is the address of the 4250 * first byte of the page just past the end of what we want. 4251 */ 4252 out: 4253 SEGOP_GETPROT(seg, saddr, len - 1, pagev->pg_protv); 4254 return (addr); 4255 } 4256 4257 static caddr_t 4258 pr_pagev_nextprot(prpagev_t *pagev, struct seg *seg, 4259 caddr_t *saddrp, caddr_t eaddr, uint_t *protp) 4260 { 4261 /* 4262 * Our starting address is either the specified address, or the base 4263 * address from the start of the pagev. If the latter is greater, 4264 * this means a previous call to pr_pagev_fill has already scanned 4265 * further than the end of the previous mapping. 4266 */ 4267 caddr_t base = seg->s_base + pagev->pg_pnbase * PAGESIZE; 4268 caddr_t addr = MAX(*saddrp, base); 4269 ulong_t pn = seg_page(seg, addr); 4270 uint_t prot, nprot; 4271 4272 /* 4273 * If we're dealing with noreserve pages, then advance addr to 4274 * the address of the next page which has backing store. 4275 */ 4276 if (pagev->pg_incore != NULL) { 4277 while (pagev->pg_incore[pn - pagev->pg_pnbase] == 0) { 4278 if ((addr += PAGESIZE) == eaddr) { 4279 *saddrp = addr; 4280 prot = 0; 4281 goto out; 4282 } 4283 if (++pn == pagev->pg_pnbase + pagev->pg_npages) { 4284 addr = pr_pagev_fill(pagev, seg, addr, eaddr); 4285 if (addr == eaddr) { 4286 *saddrp = addr; 4287 prot = 0; 4288 goto out; 4289 } 4290 pn = seg_page(seg, addr); 4291 } 4292 } 4293 } 4294 4295 /* 4296 * Get the protections on the page corresponding to addr. 4297 */ 4298 pn = seg_page(seg, addr); 4299 ASSERT(pn >= pagev->pg_pnbase); 4300 ASSERT(pn < (pagev->pg_pnbase + pagev->pg_npages)); 4301 4302 prot = pagev->pg_protv[pn - pagev->pg_pnbase]; 4303 getwatchprot(seg->s_as, addr, &prot); 4304 *saddrp = addr; 4305 4306 /* 4307 * Now loop until we find a backed page with different protections 4308 * or we reach the end of this segment. 4309 */ 4310 while ((addr += PAGESIZE) < eaddr) { 4311 /* 4312 * If pn has advanced to the page number following what we 4313 * have information on, refill the page vector and reset 4314 * addr and pn. If pr_pagev_fill does not return the 4315 * address of the next page, we have a discontiguity and 4316 * thus have reached the end of the current mapping. 4317 */ 4318 if (++pn == pagev->pg_pnbase + pagev->pg_npages) { 4319 caddr_t naddr = pr_pagev_fill(pagev, seg, addr, eaddr); 4320 if (naddr != addr) 4321 goto out; 4322 pn = seg_page(seg, addr); 4323 } 4324 4325 /* 4326 * The previous page's protections are in prot, and it has 4327 * backing. If this page is MAP_NORESERVE and has no backing, 4328 * then end this mapping and return the previous protections. 4329 */ 4330 if (pagev->pg_incore != NULL && 4331 pagev->pg_incore[pn - pagev->pg_pnbase] == 0) 4332 break; 4333 4334 /* 4335 * Otherwise end the mapping if this page's protections (nprot) 4336 * are different than those in the previous page (prot). 4337 */ 4338 nprot = pagev->pg_protv[pn - pagev->pg_pnbase]; 4339 getwatchprot(seg->s_as, addr, &nprot); 4340 4341 if (nprot != prot) 4342 break; 4343 } 4344 4345 out: 4346 *protp = prot; 4347 return (addr); 4348 } 4349 4350 size_t 4351 pr_getsegsize(struct seg *seg, int reserved) 4352 { 4353 size_t size = seg->s_size; 4354 4355 /* 4356 * If we're interested in the reserved space, return the size of the 4357 * segment itself. Everything else in this function is a special case 4358 * to determine the actual underlying size of various segment types. 4359 */ 4360 if (reserved) 4361 return (size); 4362 4363 /* 4364 * If this is a segvn mapping of a regular file, return the smaller 4365 * of the segment size and the remaining size of the file beyond 4366 * the file offset corresponding to seg->s_base. 4367 */ 4368 if (seg->s_ops == &segvn_ops) { 4369 vattr_t vattr; 4370 vnode_t *vp; 4371 4372 vattr.va_mask = AT_SIZE; 4373 4374 if (SEGOP_GETVP(seg, seg->s_base, &vp) == 0 && 4375 vp != NULL && vp->v_type == VREG && 4376 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) { 4377 4378 u_offset_t fsize = vattr.va_size; 4379 u_offset_t offset = SEGOP_GETOFFSET(seg, seg->s_base); 4380 4381 if (fsize < offset) 4382 fsize = 0; 4383 else 4384 fsize -= offset; 4385 4386 fsize = roundup(fsize, (u_offset_t)PAGESIZE); 4387 4388 if (fsize < (u_offset_t)size) 4389 size = (size_t)fsize; 4390 } 4391 4392 return (size); 4393 } 4394 4395 /* 4396 * If this is an ISM shared segment, don't include pages that are 4397 * beyond the real size of the spt segment that backs it. 4398 */ 4399 if (seg->s_ops == &segspt_shmops) 4400 return (MIN(spt_realsize(seg), size)); 4401 4402 /* 4403 * If this is segment is a mapping from /dev/null, then this is a 4404 * reservation of virtual address space and has no actual size. 4405 * Such segments are backed by segdev and have type set to neither 4406 * MAP_SHARED nor MAP_PRIVATE. 4407 */ 4408 if (seg->s_ops == &segdev_ops && 4409 ((SEGOP_GETTYPE(seg, seg->s_base) & 4410 (MAP_SHARED | MAP_PRIVATE)) == 0)) 4411 return (0); 4412 4413 /* 4414 * If this segment doesn't match one of the special types we handle, 4415 * just return the size of the segment itself. 4416 */ 4417 return (size); 4418 } 4419 4420 uint_t 4421 pr_getprot(struct seg *seg, int reserved, void **tmp, 4422 caddr_t *saddrp, caddr_t *naddrp, caddr_t eaddr) 4423 { 4424 struct as *as = seg->s_as; 4425 4426 caddr_t saddr = *saddrp; 4427 caddr_t naddr; 4428 4429 int check_noreserve; 4430 uint_t prot; 4431 4432 union { 4433 struct segvn_data *svd; 4434 struct segdev_data *sdp; 4435 void *data; 4436 } s; 4437 4438 s.data = seg->s_data; 4439 4440 ASSERT(AS_WRITE_HELD(as)); 4441 ASSERT(saddr >= seg->s_base && saddr < eaddr); 4442 ASSERT(eaddr <= seg->s_base + seg->s_size); 4443 4444 /* 4445 * Don't include MAP_NORESERVE pages in the address range 4446 * unless their mappings have actually materialized. 4447 * We cheat by knowing that segvn is the only segment 4448 * driver that supports MAP_NORESERVE. 4449 */ 4450 check_noreserve = 4451 (!reserved && seg->s_ops == &segvn_ops && s.svd != NULL && 4452 (s.svd->vp == NULL || s.svd->vp->v_type != VREG) && 4453 (s.svd->flags & MAP_NORESERVE)); 4454 4455 /* 4456 * Examine every page only as a last resort. We use guilty knowledge 4457 * of segvn and segdev to avoid this: if there are no per-page 4458 * protections present in the segment and we don't care about 4459 * MAP_NORESERVE, then s_data->prot is the prot for the whole segment. 4460 */ 4461 if (!check_noreserve && saddr == seg->s_base && 4462 seg->s_ops == &segvn_ops && s.svd != NULL && s.svd->pageprot == 0) { 4463 prot = s.svd->prot; 4464 getwatchprot(as, saddr, &prot); 4465 naddr = eaddr; 4466 4467 } else if (saddr == seg->s_base && seg->s_ops == &segdev_ops && 4468 s.sdp != NULL && s.sdp->pageprot == 0) { 4469 prot = s.sdp->prot; 4470 getwatchprot(as, saddr, &prot); 4471 naddr = eaddr; 4472 4473 } else { 4474 prpagev_t *pagev; 4475 4476 /* 4477 * If addr is sitting at the start of the segment, then 4478 * create a page vector to store protection and incore 4479 * information for pages in the segment, and fill it. 4480 * Otherwise, we expect *tmp to address the prpagev_t 4481 * allocated by a previous call to this function. 4482 */ 4483 if (saddr == seg->s_base) { 4484 pagev = pr_pagev_create(seg, check_noreserve); 4485 saddr = pr_pagev_fill(pagev, seg, saddr, eaddr); 4486 4487 ASSERT(*tmp == NULL); 4488 *tmp = pagev; 4489 4490 ASSERT(saddr <= eaddr); 4491 *saddrp = saddr; 4492 4493 if (saddr == eaddr) { 4494 naddr = saddr; 4495 prot = 0; 4496 goto out; 4497 } 4498 4499 } else { 4500 ASSERT(*tmp != NULL); 4501 pagev = (prpagev_t *)*tmp; 4502 } 4503 4504 naddr = pr_pagev_nextprot(pagev, seg, saddrp, eaddr, &prot); 4505 ASSERT(naddr <= eaddr); 4506 } 4507 4508 out: 4509 if (naddr == eaddr) 4510 pr_getprot_done(tmp); 4511 *naddrp = naddr; 4512 return (prot); 4513 } 4514 4515 void 4516 pr_getprot_done(void **tmp) 4517 { 4518 if (*tmp != NULL) { 4519 pr_pagev_destroy((prpagev_t *)*tmp); 4520 *tmp = NULL; 4521 } 4522 } 4523 4524 /* 4525 * Return true iff the vnode is a /proc file from the object directory. 4526 */ 4527 int 4528 pr_isobject(vnode_t *vp) 4529 { 4530 return (vn_matchops(vp, prvnodeops) && VTOP(vp)->pr_type == PR_OBJECT); 4531 } 4532 4533 /* 4534 * Return true iff the vnode is a /proc file opened by the process itself. 4535 */ 4536 int 4537 pr_isself(vnode_t *vp) 4538 { 4539 /* 4540 * XXX: To retain binary compatibility with the old 4541 * ioctl()-based version of /proc, we exempt self-opens 4542 * of /proc/<pid> from being marked close-on-exec. 4543 */ 4544 return (vn_matchops(vp, prvnodeops) && 4545 (VTOP(vp)->pr_flags & PR_ISSELF) && 4546 VTOP(vp)->pr_type != PR_PIDDIR); 4547 } 4548 4549 static ssize_t 4550 pr_getpagesize(struct seg *seg, caddr_t saddr, caddr_t *naddrp, caddr_t eaddr) 4551 { 4552 ssize_t pagesize, hatsize; 4553 4554 ASSERT(AS_WRITE_HELD(seg->s_as)); 4555 ASSERT(IS_P2ALIGNED(saddr, PAGESIZE)); 4556 ASSERT(IS_P2ALIGNED(eaddr, PAGESIZE)); 4557 ASSERT(saddr < eaddr); 4558 4559 pagesize = hatsize = hat_getpagesize(seg->s_as->a_hat, saddr); 4560 ASSERT(pagesize == -1 || IS_P2ALIGNED(pagesize, pagesize)); 4561 ASSERT(pagesize != 0); 4562 4563 if (pagesize == -1) 4564 pagesize = PAGESIZE; 4565 4566 saddr += P2NPHASE((uintptr_t)saddr, pagesize); 4567 4568 while (saddr < eaddr) { 4569 if (hatsize != hat_getpagesize(seg->s_as->a_hat, saddr)) 4570 break; 4571 ASSERT(IS_P2ALIGNED(saddr, pagesize)); 4572 saddr += pagesize; 4573 } 4574 4575 *naddrp = ((saddr < eaddr) ? saddr : eaddr); 4576 return (hatsize); 4577 } 4578 4579 /* 4580 * Return an array of structures with extended memory map information. 4581 * We allocate here; the caller must deallocate. 4582 */ 4583 int 4584 prgetxmap(proc_t *p, list_t *iolhead) 4585 { 4586 struct as *as = p->p_as; 4587 prxmap_t *mp; 4588 struct seg *seg; 4589 struct seg *brkseg, *stkseg; 4590 struct vnode *vp; 4591 struct vattr vattr; 4592 uint_t prot; 4593 4594 ASSERT(as != &kas && AS_WRITE_HELD(as)); 4595 4596 /* 4597 * Request an initial buffer size that doesn't waste memory 4598 * if the address space has only a small number of segments. 4599 */ 4600 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 4601 4602 if ((seg = AS_SEGFIRST(as)) == NULL) 4603 return (0); 4604 4605 brkseg = break_seg(p); 4606 stkseg = as_segat(as, prgetstackbase(p)); 4607 4608 do { 4609 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 4610 caddr_t saddr, naddr, baddr; 4611 void *tmp = NULL; 4612 ssize_t psz; 4613 char *parr; 4614 uint64_t npages; 4615 uint64_t pagenum; 4616 4617 if ((seg->s_flags & S_HOLE) != 0) { 4618 continue; 4619 } 4620 /* 4621 * Segment loop part one: iterate from the base of the segment 4622 * to its end, pausing at each address boundary (baddr) between 4623 * ranges that have different virtual memory protections. 4624 */ 4625 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) { 4626 prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr); 4627 ASSERT(baddr >= saddr && baddr <= eaddr); 4628 4629 /* 4630 * Segment loop part two: iterate from the current 4631 * position to the end of the protection boundary, 4632 * pausing at each address boundary (naddr) between 4633 * ranges that have different underlying page sizes. 4634 */ 4635 for (; saddr < baddr; saddr = naddr) { 4636 psz = pr_getpagesize(seg, saddr, &naddr, baddr); 4637 ASSERT(naddr >= saddr && naddr <= baddr); 4638 4639 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 4640 4641 mp->pr_vaddr = (uintptr_t)saddr; 4642 mp->pr_size = naddr - saddr; 4643 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr); 4644 mp->pr_mflags = 0; 4645 if (prot & PROT_READ) 4646 mp->pr_mflags |= MA_READ; 4647 if (prot & PROT_WRITE) 4648 mp->pr_mflags |= MA_WRITE; 4649 if (prot & PROT_EXEC) 4650 mp->pr_mflags |= MA_EXEC; 4651 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 4652 mp->pr_mflags |= MA_SHARED; 4653 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE) 4654 mp->pr_mflags |= MA_NORESERVE; 4655 if (seg->s_ops == &segspt_shmops || 4656 (seg->s_ops == &segvn_ops && 4657 (SEGOP_GETVP(seg, saddr, &vp) != 0 || 4658 vp == NULL))) 4659 mp->pr_mflags |= MA_ANON; 4660 if (seg == brkseg) 4661 mp->pr_mflags |= MA_BREAK; 4662 else if (seg == stkseg) 4663 mp->pr_mflags |= MA_STACK; 4664 if (seg->s_ops == &segspt_shmops) 4665 mp->pr_mflags |= MA_ISM | MA_SHM; 4666 4667 mp->pr_pagesize = PAGESIZE; 4668 if (psz == -1) { 4669 mp->pr_hatpagesize = 0; 4670 } else { 4671 mp->pr_hatpagesize = psz; 4672 } 4673 4674 /* 4675 * Manufacture a filename for the "object" dir. 4676 */ 4677 mp->pr_dev = PRNODEV; 4678 vattr.va_mask = AT_FSID|AT_NODEID; 4679 if (seg->s_ops == &segvn_ops && 4680 SEGOP_GETVP(seg, saddr, &vp) == 0 && 4681 vp != NULL && vp->v_type == VREG && 4682 VOP_GETATTR(vp, &vattr, 0, CRED(), 4683 NULL) == 0) { 4684 mp->pr_dev = vattr.va_fsid; 4685 mp->pr_ino = vattr.va_nodeid; 4686 if (vp == p->p_exec) 4687 (void) strcpy(mp->pr_mapname, 4688 "a.out"); 4689 else 4690 pr_object_name(mp->pr_mapname, 4691 vp, &vattr); 4692 } 4693 4694 /* 4695 * Get the SysV shared memory id, if any. 4696 */ 4697 if ((mp->pr_mflags & MA_SHARED) && 4698 p->p_segacct && (mp->pr_shmid = shmgetid(p, 4699 seg->s_base)) != SHMID_NONE) { 4700 if (mp->pr_shmid == SHMID_FREE) 4701 mp->pr_shmid = -1; 4702 4703 mp->pr_mflags |= MA_SHM; 4704 } else { 4705 mp->pr_shmid = -1; 4706 } 4707 4708 npages = ((uintptr_t)(naddr - saddr)) >> 4709 PAGESHIFT; 4710 parr = kmem_zalloc(npages, KM_SLEEP); 4711 4712 SEGOP_INCORE(seg, saddr, naddr - saddr, parr); 4713 4714 for (pagenum = 0; pagenum < npages; pagenum++) { 4715 if (parr[pagenum] & SEG_PAGE_INCORE) 4716 mp->pr_rss++; 4717 if (parr[pagenum] & SEG_PAGE_ANON) 4718 mp->pr_anon++; 4719 if (parr[pagenum] & SEG_PAGE_LOCKED) 4720 mp->pr_locked++; 4721 } 4722 kmem_free(parr, npages); 4723 } 4724 } 4725 ASSERT(tmp == NULL); 4726 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 4727 4728 return (0); 4729 } 4730 4731 /* 4732 * Return the process's credentials. We don't need a 32-bit equivalent of 4733 * this function because prcred_t and prcred32_t are actually the same. 4734 */ 4735 void 4736 prgetcred(proc_t *p, prcred_t *pcrp) 4737 { 4738 mutex_enter(&p->p_crlock); 4739 cred2prcred(p->p_cred, pcrp); 4740 mutex_exit(&p->p_crlock); 4741 } 4742 4743 void 4744 prgetsecflags(proc_t *p, prsecflags_t *psfp) 4745 { 4746 ASSERT(psfp != NULL); 4747 4748 psfp->pr_version = PRSECFLAGS_VERSION_CURRENT; 4749 psfp->pr_lower = p->p_secflags.psf_lower; 4750 psfp->pr_upper = p->p_secflags.psf_upper; 4751 psfp->pr_effective = p->p_secflags.psf_effective; 4752 psfp->pr_inherit = p->p_secflags.psf_inherit; 4753 } 4754 4755 /* 4756 * Compute actual size of the prpriv_t structure. 4757 */ 4758 4759 size_t 4760 prgetprivsize(void) 4761 { 4762 return (priv_prgetprivsize(NULL)); 4763 } 4764 4765 /* 4766 * Return the process's privileges. We don't need a 32-bit equivalent of 4767 * this function because prpriv_t and prpriv32_t are actually the same. 4768 */ 4769 void 4770 prgetpriv(proc_t *p, prpriv_t *pprp) 4771 { 4772 mutex_enter(&p->p_crlock); 4773 cred2prpriv(p->p_cred, pprp); 4774 mutex_exit(&p->p_crlock); 4775 } 4776 4777 #ifdef _SYSCALL32_IMPL 4778 /* 4779 * Return an array of structures with HAT memory map information. 4780 * We allocate here; the caller must deallocate. 4781 */ 4782 int 4783 prgetxmap32(proc_t *p, list_t *iolhead) 4784 { 4785 struct as *as = p->p_as; 4786 prxmap32_t *mp; 4787 struct seg *seg; 4788 struct seg *brkseg, *stkseg; 4789 struct vnode *vp; 4790 struct vattr vattr; 4791 uint_t prot; 4792 4793 ASSERT(as != &kas && AS_WRITE_HELD(as)); 4794 4795 /* 4796 * Request an initial buffer size that doesn't waste memory 4797 * if the address space has only a small number of segments. 4798 */ 4799 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree)); 4800 4801 if ((seg = AS_SEGFIRST(as)) == NULL) 4802 return (0); 4803 4804 brkseg = break_seg(p); 4805 stkseg = as_segat(as, prgetstackbase(p)); 4806 4807 do { 4808 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0); 4809 caddr_t saddr, naddr, baddr; 4810 void *tmp = NULL; 4811 ssize_t psz; 4812 char *parr; 4813 uint64_t npages; 4814 uint64_t pagenum; 4815 4816 if ((seg->s_flags & S_HOLE) != 0) { 4817 continue; 4818 } 4819 4820 /* 4821 * Segment loop part one: iterate from the base of the segment 4822 * to its end, pausing at each address boundary (baddr) between 4823 * ranges that have different virtual memory protections. 4824 */ 4825 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) { 4826 prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr); 4827 ASSERT(baddr >= saddr && baddr <= eaddr); 4828 4829 /* 4830 * Segment loop part two: iterate from the current 4831 * position to the end of the protection boundary, 4832 * pausing at each address boundary (naddr) between 4833 * ranges that have different underlying page sizes. 4834 */ 4835 for (; saddr < baddr; saddr = naddr) { 4836 psz = pr_getpagesize(seg, saddr, &naddr, baddr); 4837 ASSERT(naddr >= saddr && naddr <= baddr); 4838 4839 mp = pr_iol_newbuf(iolhead, sizeof (*mp)); 4840 4841 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr; 4842 mp->pr_size = (size32_t)(naddr - saddr); 4843 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr); 4844 mp->pr_mflags = 0; 4845 if (prot & PROT_READ) 4846 mp->pr_mflags |= MA_READ; 4847 if (prot & PROT_WRITE) 4848 mp->pr_mflags |= MA_WRITE; 4849 if (prot & PROT_EXEC) 4850 mp->pr_mflags |= MA_EXEC; 4851 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED) 4852 mp->pr_mflags |= MA_SHARED; 4853 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE) 4854 mp->pr_mflags |= MA_NORESERVE; 4855 if (seg->s_ops == &segspt_shmops || 4856 (seg->s_ops == &segvn_ops && 4857 (SEGOP_GETVP(seg, saddr, &vp) != 0 || 4858 vp == NULL))) 4859 mp->pr_mflags |= MA_ANON; 4860 if (seg == brkseg) 4861 mp->pr_mflags |= MA_BREAK; 4862 else if (seg == stkseg) 4863 mp->pr_mflags |= MA_STACK; 4864 if (seg->s_ops == &segspt_shmops) 4865 mp->pr_mflags |= MA_ISM | MA_SHM; 4866 4867 mp->pr_pagesize = PAGESIZE; 4868 if (psz == -1) { 4869 mp->pr_hatpagesize = 0; 4870 } else { 4871 mp->pr_hatpagesize = psz; 4872 } 4873 4874 /* 4875 * Manufacture a filename for the "object" dir. 4876 */ 4877 mp->pr_dev = PRNODEV32; 4878 vattr.va_mask = AT_FSID|AT_NODEID; 4879 if (seg->s_ops == &segvn_ops && 4880 SEGOP_GETVP(seg, saddr, &vp) == 0 && 4881 vp != NULL && vp->v_type == VREG && 4882 VOP_GETATTR(vp, &vattr, 0, CRED(), 4883 NULL) == 0) { 4884 (void) cmpldev(&mp->pr_dev, 4885 vattr.va_fsid); 4886 mp->pr_ino = vattr.va_nodeid; 4887 if (vp == p->p_exec) 4888 (void) strcpy(mp->pr_mapname, 4889 "a.out"); 4890 else 4891 pr_object_name(mp->pr_mapname, 4892 vp, &vattr); 4893 } 4894 4895 /* 4896 * Get the SysV shared memory id, if any. 4897 */ 4898 if ((mp->pr_mflags & MA_SHARED) && 4899 p->p_segacct && (mp->pr_shmid = shmgetid(p, 4900 seg->s_base)) != SHMID_NONE) { 4901 if (mp->pr_shmid == SHMID_FREE) 4902 mp->pr_shmid = -1; 4903 4904 mp->pr_mflags |= MA_SHM; 4905 } else { 4906 mp->pr_shmid = -1; 4907 } 4908 4909 npages = ((uintptr_t)(naddr - saddr)) >> 4910 PAGESHIFT; 4911 parr = kmem_zalloc(npages, KM_SLEEP); 4912 4913 SEGOP_INCORE(seg, saddr, naddr - saddr, parr); 4914 4915 for (pagenum = 0; pagenum < npages; pagenum++) { 4916 if (parr[pagenum] & SEG_PAGE_INCORE) 4917 mp->pr_rss++; 4918 if (parr[pagenum] & SEG_PAGE_ANON) 4919 mp->pr_anon++; 4920 if (parr[pagenum] & SEG_PAGE_LOCKED) 4921 mp->pr_locked++; 4922 } 4923 kmem_free(parr, npages); 4924 } 4925 } 4926 ASSERT(tmp == NULL); 4927 } while ((seg = AS_SEGNEXT(as, seg)) != NULL); 4928 4929 return (0); 4930 } 4931 #endif /* _SYSCALL32_IMPL */ 4932