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