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