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