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 THREAD_KPRI_REQUEST();
707 return (p);
708 }
709
710 /*
711 * Lock the target process by setting P_PR_LOCK and grabbing p->p_lock.
712 * This prevents any lwp of the process from disappearing and
713 * blocks most operations that a process can perform on itself.
714 * Returns 0 on success, a non-zero error number on failure.
715 *
716 * 'zdisp' is ZYES or ZNO to indicate whether prlock() should succeed when
717 * the subject process is a zombie (ZYES) or fail for zombies (ZNO).
718 *
719 * error returns:
720 * ENOENT: process or lwp has disappeared or process is exiting
721 * (or has become a zombie and zdisp == ZNO).
722 * EAGAIN: procfs vnode has become invalid.
723 * EINTR: signal arrived while waiting for exec to complete.
724 */
725 int
726 prlock(prnode_t *pnp, int zdisp)
727 {
728 prcommon_t *pcp;
729 proc_t *p;
730
731 again:
732 pcp = pnp->pr_common;
733 p = pr_p_lock(pnp);
734 mutex_exit(&pr_pidlock);
735
736 /*
737 * Return ENOENT immediately if there is no process.
738 */
739 if (p == NULL)
740 return (ENOENT);
741
742 ASSERT(p == pcp->prc_proc && p->p_stat != 0 && p->p_stat != SIDL);
743
744 /*
745 * Return ENOENT if process entered zombie state or is exiting
746 * and the 'zdisp' flag is set to ZNO indicating not to lock zombies.
747 */
748 if (zdisp == ZNO &&
749 ((pcp->prc_flags & PRC_DESTROY) || (p->p_flag & SEXITING))) {
750 prunlock(pnp);
751 return (ENOENT);
752 }
753
754 /*
755 * If lwp-specific, check to see if lwp has disappeared.
756 */
757 if (pcp->prc_flags & PRC_LWP) {
758 if ((zdisp == ZNO && (pcp->prc_flags & PRC_DESTROY)) ||
759 pcp->prc_tslot == -1) {
760 prunlock(pnp);
761 return (ENOENT);
762 }
763 }
764
765 /*
766 * Return EAGAIN if we have encountered a security violation.
767 * (The process exec'd a set-id or unreadable executable file.)
768 */
769 if (pnp->pr_flags & PR_INVAL) {
770 prunlock(pnp);
771 return (EAGAIN);
772 }
773
774 /*
775 * If process is undergoing an exec(), wait for
776 * completion and then start all over again.
777 */
778 if (p->p_proc_flag & P_PR_EXEC) {
779 pcp = pnp->pr_pcommon; /* Put on the correct sleep queue */
780 mutex_enter(&pcp->prc_mutex);
781 prunlock(pnp);
782 if (!cv_wait_sig(&pcp->prc_wait, &pcp->prc_mutex)) {
783 mutex_exit(&pcp->prc_mutex);
784 return (EINTR);
785 }
786 mutex_exit(&pcp->prc_mutex);
787 goto again;
788 }
789
790 /*
791 * We return holding p->p_lock.
792 */
793 return (0);
794 }
795
796 /*
797 * Undo prlock() and pr_p_lock().
798 * p->p_lock is still held; pr_pidlock is no longer held.
799 *
800 * prunmark() drops the P_PR_LOCK flag and wakes up another thread,
801 * if any, waiting for the flag to be dropped; it retains p->p_lock.
802 *
803 * prunlock() calls prunmark() and then drops p->p_lock.
804 */
805 void
806 prunmark(proc_t *p)
807 {
808 ASSERT(p->p_proc_flag & P_PR_LOCK);
809 ASSERT(MUTEX_HELD(&p->p_lock));
810
811 cv_signal(&pr_pid_cv[p->p_slot]);
812 p->p_proc_flag &= ~P_PR_LOCK;
813 THREAD_KPRI_RELEASE();
814 }
815
816 void
817 prunlock(prnode_t *pnp)
818 {
819 prcommon_t *pcp = pnp->pr_common;
820 proc_t *p = pcp->prc_proc;
821
822 /*
823 * If we (or someone) gave it a SIGKILL, and it is not
824 * already a zombie, set it running unconditionally.
825 */
826 if ((p->p_flag & SKILLED) &&
827 !(p->p_flag & SEXITING) &&
828 !(pcp->prc_flags & PRC_DESTROY) &&
829 !((pcp->prc_flags & PRC_LWP) && pcp->prc_tslot == -1))
830 (void) pr_setrun(pnp, 0);
831 prunmark(p);
832 mutex_exit(&p->p_lock);
833 }
834
835 /*
836 * Called while holding p->p_lock to delay until the process is unlocked.
837 * We enter holding p->p_lock; p->p_lock is dropped and reacquired.
838 * The process cannot become locked again until p->p_lock is dropped.
839 */
840 void
841 prbarrier(proc_t *p)
842 {
843 ASSERT(MUTEX_HELD(&p->p_lock));
844
845 if (p->p_proc_flag & P_PR_LOCK) {
846 /* The process is locked; delay until not locked */
847 uint_t slot = p->p_slot;
848
849 while (p->p_proc_flag & P_PR_LOCK)
850 cv_wait(&pr_pid_cv[slot], &p->p_lock);
851 cv_signal(&pr_pid_cv[slot]);
852 }
853 }
854
855 /*
856 * Return process/lwp status.
857 * The u-block is mapped in by this routine and unmapped at the end.
858 */
859 void
860 prgetstatus(proc_t *p, pstatus_t *sp, zone_t *zp)
861 {
862 kthread_t *t;
863
864 ASSERT(MUTEX_HELD(&p->p_lock));
865
866 t = prchoose(p); /* returns locked thread */
867 ASSERT(t != NULL);
868 thread_unlock(t);
869
870 /* just bzero the process part, prgetlwpstatus() does the rest */
871 bzero(sp, sizeof (pstatus_t) - sizeof (lwpstatus_t));
872 sp->pr_nlwp = p->p_lwpcnt;
873 sp->pr_nzomb = p->p_zombcnt;
874 prassignset(&sp->pr_sigpend, &p->p_sig);
875 sp->pr_brkbase = (uintptr_t)p->p_brkbase;
876 sp->pr_brksize = p->p_brksize;
877 sp->pr_stkbase = (uintptr_t)prgetstackbase(p);
878 sp->pr_stksize = p->p_stksize;
879 sp->pr_pid = p->p_pid;
880 if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
881 (p->p_flag & SZONETOP)) {
882 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
883 /*
884 * Inside local zones, fake zsched's pid as parent pids for
885 * processes which reference processes outside of the zone.
886 */
887 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
888 } else {
889 sp->pr_ppid = p->p_ppid;
890 }
891 sp->pr_pgid = p->p_pgrp;
892 sp->pr_sid = p->p_sessp->s_sid;
893 sp->pr_taskid = p->p_task->tk_tkid;
894 sp->pr_projid = p->p_task->tk_proj->kpj_id;
895 sp->pr_zoneid = p->p_zone->zone_id;
896 bcopy(&p->p_secflags, &sp->pr_secflags, sizeof (psecflags_t));
897 hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
898 hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
899 TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime);
900 TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime);
901 prassignset(&sp->pr_sigtrace, &p->p_sigmask);
902 prassignset(&sp->pr_flttrace, &p->p_fltmask);
903 prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
904 prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
905 switch (p->p_model) {
906 case DATAMODEL_ILP32:
907 sp->pr_dmodel = PR_MODEL_ILP32;
908 break;
909 case DATAMODEL_LP64:
910 sp->pr_dmodel = PR_MODEL_LP64;
911 break;
912 }
913 if (p->p_agenttp)
914 sp->pr_agentid = p->p_agenttp->t_tid;
915
916 /* get the chosen lwp's status */
917 prgetlwpstatus(t, &sp->pr_lwp, zp);
918
919 /* replicate the flags */
920 sp->pr_flags = sp->pr_lwp.pr_flags;
921 }
922
923 #ifdef _SYSCALL32_IMPL
924 void
925 prgetlwpstatus32(kthread_t *t, lwpstatus32_t *sp, zone_t *zp)
926 {
927 proc_t *p = ttoproc(t);
928 klwp_t *lwp = ttolwp(t);
929 struct mstate *ms = &lwp->lwp_mstate;
930 hrtime_t usr, sys;
931 int flags;
932 ulong_t instr;
933
934 ASSERT(MUTEX_HELD(&p->p_lock));
935
936 bzero(sp, sizeof (*sp));
937 flags = 0L;
938 if (t->t_state == TS_STOPPED) {
939 flags |= PR_STOPPED;
940 if ((t->t_schedflag & TS_PSTART) == 0)
941 flags |= PR_ISTOP;
942 } else if (VSTOPPED(t)) {
943 flags |= PR_STOPPED|PR_ISTOP;
944 }
945 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
946 flags |= PR_DSTOP;
947 if (lwp->lwp_asleep)
948 flags |= PR_ASLEEP;
949 if (t == p->p_agenttp)
950 flags |= PR_AGENT;
951 if (!(t->t_proc_flag & TP_TWAIT))
952 flags |= PR_DETACH;
953 if (t->t_proc_flag & TP_DAEMON)
954 flags |= PR_DAEMON;
955 if (p->p_proc_flag & P_PR_FORK)
956 flags |= PR_FORK;
957 if (p->p_proc_flag & P_PR_RUNLCL)
958 flags |= PR_RLC;
959 if (p->p_proc_flag & P_PR_KILLCL)
960 flags |= PR_KLC;
961 if (p->p_proc_flag & P_PR_ASYNC)
962 flags |= PR_ASYNC;
963 if (p->p_proc_flag & P_PR_BPTADJ)
964 flags |= PR_BPTADJ;
965 if (p->p_proc_flag & P_PR_PTRACE)
966 flags |= PR_PTRACE;
967 if (p->p_flag & SMSACCT)
968 flags |= PR_MSACCT;
969 if (p->p_flag & SMSFORK)
970 flags |= PR_MSFORK;
971 if (p->p_flag & SVFWAIT)
972 flags |= PR_VFORKP;
973 sp->pr_flags = flags;
974 if (VSTOPPED(t)) {
975 sp->pr_why = PR_REQUESTED;
976 sp->pr_what = 0;
977 } else {
978 sp->pr_why = t->t_whystop;
979 sp->pr_what = t->t_whatstop;
980 }
981 sp->pr_lwpid = t->t_tid;
982 sp->pr_cursig = lwp->lwp_cursig;
983 prassignset(&sp->pr_lwppend, &t->t_sig);
984 schedctl_finish_sigblock(t);
985 prassignset(&sp->pr_lwphold, &t->t_hold);
986 if (t->t_whystop == PR_FAULTED) {
987 siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info);
988 if (t->t_whatstop == FLTPAGE)
989 sp->pr_info.si_addr =
990 (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr;
991 } else if (lwp->lwp_curinfo)
992 siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info);
993 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
994 sp->pr_info.si_zoneid != zp->zone_id) {
995 sp->pr_info.si_pid = zp->zone_zsched->p_pid;
996 sp->pr_info.si_uid = 0;
997 sp->pr_info.si_ctid = -1;
998 sp->pr_info.si_zoneid = zp->zone_id;
999 }
1000 sp->pr_altstack.ss_sp =
1001 (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp;
1002 sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size;
1003 sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags;
1004 prgetaction32(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1005 sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext;
1006 sp->pr_ustack = (caddr32_t)lwp->lwp_ustack;
1007 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1008 sizeof (sp->pr_clname) - 1);
1009 if (flags & PR_STOPPED)
1010 hrt2ts32(t->t_stoptime, &sp->pr_tstamp);
1011 usr = ms->ms_acct[LMS_USER];
1012 sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1013 scalehrtime(&usr);
1014 scalehrtime(&sys);
1015 hrt2ts32(usr, &sp->pr_utime);
1016 hrt2ts32(sys, &sp->pr_stime);
1017
1018 /*
1019 * Fetch the current instruction, if not a system process.
1020 * We don't attempt this unless the lwp is stopped.
1021 */
1022 if ((p->p_flag & SSYS) || p->p_as == &kas)
1023 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1024 else if (!(flags & PR_STOPPED))
1025 sp->pr_flags |= PR_PCINVAL;
1026 else if (!prfetchinstr(lwp, &instr))
1027 sp->pr_flags |= PR_PCINVAL;
1028 else
1029 sp->pr_instr = (uint32_t)instr;
1030
1031 /*
1032 * Drop p_lock while touching the lwp's stack.
1033 */
1034 mutex_exit(&p->p_lock);
1035 if (prisstep(lwp))
1036 sp->pr_flags |= PR_STEP;
1037 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1038 int i;
1039
1040 sp->pr_syscall = get_syscall32_args(lwp,
1041 (int *)sp->pr_sysarg, &i);
1042 sp->pr_nsysarg = (ushort_t)i;
1043 }
1044 if ((flags & PR_STOPPED) || t == curthread)
1045 prgetprregs32(lwp, sp->pr_reg);
1046 if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1047 (flags & PR_VFORKP)) {
1048 long r1, r2;
1049 user_t *up;
1050 auxv_t *auxp;
1051 int i;
1052
1053 sp->pr_errno = prgetrvals(lwp, &r1, &r2);
1054 if (sp->pr_errno == 0) {
1055 sp->pr_rval1 = (int32_t)r1;
1056 sp->pr_rval2 = (int32_t)r2;
1057 sp->pr_errpriv = PRIV_NONE;
1058 } else
1059 sp->pr_errpriv = lwp->lwp_badpriv;
1060
1061 if (t->t_sysnum == SYS_execve) {
1062 up = PTOU(p);
1063 sp->pr_sysarg[0] = 0;
1064 sp->pr_sysarg[1] = (caddr32_t)up->u_argv;
1065 sp->pr_sysarg[2] = (caddr32_t)up->u_envp;
1066 for (i = 0, auxp = up->u_auxv;
1067 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1068 i++, auxp++) {
1069 if (auxp->a_type == AT_SUN_EXECNAME) {
1070 sp->pr_sysarg[0] =
1071 (caddr32_t)
1072 (uintptr_t)auxp->a_un.a_ptr;
1073 break;
1074 }
1075 }
1076 }
1077 }
1078 if (prhasfp())
1079 prgetprfpregs32(lwp, &sp->pr_fpreg);
1080 mutex_enter(&p->p_lock);
1081 }
1082
1083 void
1084 prgetstatus32(proc_t *p, pstatus32_t *sp, zone_t *zp)
1085 {
1086 kthread_t *t;
1087
1088 ASSERT(MUTEX_HELD(&p->p_lock));
1089
1090 t = prchoose(p); /* returns locked thread */
1091 ASSERT(t != NULL);
1092 thread_unlock(t);
1093
1094 /* just bzero the process part, prgetlwpstatus32() does the rest */
1095 bzero(sp, sizeof (pstatus32_t) - sizeof (lwpstatus32_t));
1096 sp->pr_nlwp = p->p_lwpcnt;
1097 sp->pr_nzomb = p->p_zombcnt;
1098 prassignset(&sp->pr_sigpend, &p->p_sig);
1099 sp->pr_brkbase = (uint32_t)(uintptr_t)p->p_brkbase;
1100 sp->pr_brksize = (uint32_t)p->p_brksize;
1101 sp->pr_stkbase = (uint32_t)(uintptr_t)prgetstackbase(p);
1102 sp->pr_stksize = (uint32_t)p->p_stksize;
1103 sp->pr_pid = p->p_pid;
1104 if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
1105 (p->p_flag & SZONETOP)) {
1106 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
1107 /*
1108 * Inside local zones, fake zsched's pid as parent pids for
1109 * processes which reference processes outside of the zone.
1110 */
1111 sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
1112 } else {
1113 sp->pr_ppid = p->p_ppid;
1114 }
1115 sp->pr_pgid = p->p_pgrp;
1116 sp->pr_sid = p->p_sessp->s_sid;
1117 sp->pr_taskid = p->p_task->tk_tkid;
1118 sp->pr_projid = p->p_task->tk_proj->kpj_id;
1119 sp->pr_zoneid = p->p_zone->zone_id;
1120 bcopy(&p->p_secflags, &sp->pr_secflags, sizeof (psecflags_t));
1121 hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
1122 hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
1123 TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime);
1124 TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime);
1125 prassignset(&sp->pr_sigtrace, &p->p_sigmask);
1126 prassignset(&sp->pr_flttrace, &p->p_fltmask);
1127 prassignset(&sp->pr_sysentry, &PTOU(p)->u_entrymask);
1128 prassignset(&sp->pr_sysexit, &PTOU(p)->u_exitmask);
1129 switch (p->p_model) {
1130 case DATAMODEL_ILP32:
1131 sp->pr_dmodel = PR_MODEL_ILP32;
1132 break;
1133 case DATAMODEL_LP64:
1134 sp->pr_dmodel = PR_MODEL_LP64;
1135 break;
1136 }
1137 if (p->p_agenttp)
1138 sp->pr_agentid = p->p_agenttp->t_tid;
1139
1140 /* get the chosen lwp's status */
1141 prgetlwpstatus32(t, &sp->pr_lwp, zp);
1142
1143 /* replicate the flags */
1144 sp->pr_flags = sp->pr_lwp.pr_flags;
1145 }
1146 #endif /* _SYSCALL32_IMPL */
1147
1148 /*
1149 * Return lwp status.
1150 */
1151 void
1152 prgetlwpstatus(kthread_t *t, lwpstatus_t *sp, zone_t *zp)
1153 {
1154 proc_t *p = ttoproc(t);
1155 klwp_t *lwp = ttolwp(t);
1156 struct mstate *ms = &lwp->lwp_mstate;
1157 hrtime_t usr, sys;
1158 int flags;
1159 ulong_t instr;
1160
1161 ASSERT(MUTEX_HELD(&p->p_lock));
1162
1163 bzero(sp, sizeof (*sp));
1164 flags = 0L;
1165 if (t->t_state == TS_STOPPED) {
1166 flags |= PR_STOPPED;
1167 if ((t->t_schedflag & TS_PSTART) == 0)
1168 flags |= PR_ISTOP;
1169 } else if (VSTOPPED(t)) {
1170 flags |= PR_STOPPED|PR_ISTOP;
1171 }
1172 if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
1173 flags |= PR_DSTOP;
1174 if (lwp->lwp_asleep)
1175 flags |= PR_ASLEEP;
1176 if (t == p->p_agenttp)
1177 flags |= PR_AGENT;
1178 if (!(t->t_proc_flag & TP_TWAIT))
1179 flags |= PR_DETACH;
1180 if (t->t_proc_flag & TP_DAEMON)
1181 flags |= PR_DAEMON;
1182 if (p->p_proc_flag & P_PR_FORK)
1183 flags |= PR_FORK;
1184 if (p->p_proc_flag & P_PR_RUNLCL)
1185 flags |= PR_RLC;
1186 if (p->p_proc_flag & P_PR_KILLCL)
1187 flags |= PR_KLC;
1188 if (p->p_proc_flag & P_PR_ASYNC)
1189 flags |= PR_ASYNC;
1190 if (p->p_proc_flag & P_PR_BPTADJ)
1191 flags |= PR_BPTADJ;
1192 if (p->p_proc_flag & P_PR_PTRACE)
1193 flags |= PR_PTRACE;
1194 if (p->p_flag & SMSACCT)
1195 flags |= PR_MSACCT;
1196 if (p->p_flag & SMSFORK)
1197 flags |= PR_MSFORK;
1198 if (p->p_flag & SVFWAIT)
1199 flags |= PR_VFORKP;
1200 if (p->p_pgidp->pid_pgorphaned)
1201 flags |= PR_ORPHAN;
1202 if (p->p_pidflag & CLDNOSIGCHLD)
1203 flags |= PR_NOSIGCHLD;
1204 if (p->p_pidflag & CLDWAITPID)
1205 flags |= PR_WAITPID;
1206 sp->pr_flags = flags;
1207 if (VSTOPPED(t)) {
1208 sp->pr_why = PR_REQUESTED;
1209 sp->pr_what = 0;
1210 } else {
1211 sp->pr_why = t->t_whystop;
1212 sp->pr_what = t->t_whatstop;
1213 }
1214 sp->pr_lwpid = t->t_tid;
1215 sp->pr_cursig = lwp->lwp_cursig;
1216 prassignset(&sp->pr_lwppend, &t->t_sig);
1217 schedctl_finish_sigblock(t);
1218 prassignset(&sp->pr_lwphold, &t->t_hold);
1219 if (t->t_whystop == PR_FAULTED)
1220 bcopy(&lwp->lwp_siginfo,
1221 &sp->pr_info, sizeof (k_siginfo_t));
1222 else if (lwp->lwp_curinfo)
1223 bcopy(&lwp->lwp_curinfo->sq_info,
1224 &sp->pr_info, sizeof (k_siginfo_t));
1225 if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
1226 sp->pr_info.si_zoneid != zp->zone_id) {
1227 sp->pr_info.si_pid = zp->zone_zsched->p_pid;
1228 sp->pr_info.si_uid = 0;
1229 sp->pr_info.si_ctid = -1;
1230 sp->pr_info.si_zoneid = zp->zone_id;
1231 }
1232 sp->pr_altstack = lwp->lwp_sigaltstack;
1233 prgetaction(p, PTOU(p), lwp->lwp_cursig, &sp->pr_action);
1234 sp->pr_oldcontext = (uintptr_t)lwp->lwp_oldcontext;
1235 sp->pr_ustack = lwp->lwp_ustack;
1236 (void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
1237 sizeof (sp->pr_clname) - 1);
1238 if (flags & PR_STOPPED)
1239 hrt2ts(t->t_stoptime, &sp->pr_tstamp);
1240 usr = ms->ms_acct[LMS_USER];
1241 sys = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
1242 scalehrtime(&usr);
1243 scalehrtime(&sys);
1244 hrt2ts(usr, &sp->pr_utime);
1245 hrt2ts(sys, &sp->pr_stime);
1246
1247 /*
1248 * Fetch the current instruction, if not a system process.
1249 * We don't attempt this unless the lwp is stopped.
1250 */
1251 if ((p->p_flag & SSYS) || p->p_as == &kas)
1252 sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
1253 else if (!(flags & PR_STOPPED))
1254 sp->pr_flags |= PR_PCINVAL;
1255 else if (!prfetchinstr(lwp, &instr))
1256 sp->pr_flags |= PR_PCINVAL;
1257 else
1258 sp->pr_instr = instr;
1259
1260 /*
1261 * Drop p_lock while touching the lwp's stack.
1262 */
1263 mutex_exit(&p->p_lock);
1264 if (prisstep(lwp))
1265 sp->pr_flags |= PR_STEP;
1266 if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
1267 int i;
1268
1269 sp->pr_syscall = get_syscall_args(lwp,
1270 (long *)sp->pr_sysarg, &i);
1271 sp->pr_nsysarg = (ushort_t)i;
1272 }
1273 if ((flags & PR_STOPPED) || t == curthread)
1274 prgetprregs(lwp, sp->pr_reg);
1275 if ((t->t_state == TS_STOPPED && t->t_whystop == PR_SYSEXIT) ||
1276 (flags & PR_VFORKP)) {
1277 user_t *up;
1278 auxv_t *auxp;
1279 int i;
1280
1281 sp->pr_errno = prgetrvals(lwp, &sp->pr_rval1, &sp->pr_rval2);
1282 if (sp->pr_errno == 0)
1283 sp->pr_errpriv = PRIV_NONE;
1284 else
1285 sp->pr_errpriv = lwp->lwp_badpriv;
1286
1287 if (t->t_sysnum == SYS_execve) {
1288 up = PTOU(p);
1289 sp->pr_sysarg[0] = 0;
1290 sp->pr_sysarg[1] = (uintptr_t)up->u_argv;
1291 sp->pr_sysarg[2] = (uintptr_t)up->u_envp;
1292 for (i = 0, auxp = up->u_auxv;
1293 i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
1294 i++, auxp++) {
1295 if (auxp->a_type == AT_SUN_EXECNAME) {
1296 sp->pr_sysarg[0] =
1297 (uintptr_t)auxp->a_un.a_ptr;
1298 break;
1299 }
1300 }
1301 }
1302 }
1303 if (prhasfp())
1304 prgetprfpregs(lwp, &sp->pr_fpreg);
1305 mutex_enter(&p->p_lock);
1306 }
1307
1308 /*
1309 * Get the sigaction structure for the specified signal. The u-block
1310 * must already have been mapped in by the caller.
1311 */
1312 void
1313 prgetaction(proc_t *p, user_t *up, uint_t sig, struct sigaction *sp)
1314 {
1315 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1316
1317 bzero(sp, sizeof (*sp));
1318
1319 if (sig != 0 && (unsigned)sig < nsig) {
1320 sp->sa_handler = up->u_signal[sig-1];
1321 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1322 if (sigismember(&up->u_sigonstack, sig))
1323 sp->sa_flags |= SA_ONSTACK;
1324 if (sigismember(&up->u_sigresethand, sig))
1325 sp->sa_flags |= SA_RESETHAND;
1326 if (sigismember(&up->u_sigrestart, sig))
1327 sp->sa_flags |= SA_RESTART;
1328 if (sigismember(&p->p_siginfo, sig))
1329 sp->sa_flags |= SA_SIGINFO;
1330 if (sigismember(&up->u_signodefer, sig))
1331 sp->sa_flags |= SA_NODEFER;
1332 if (sig == SIGCLD) {
1333 if (p->p_flag & SNOWAIT)
1334 sp->sa_flags |= SA_NOCLDWAIT;
1335 if ((p->p_flag & SJCTL) == 0)
1336 sp->sa_flags |= SA_NOCLDSTOP;
1337 }
1338 }
1339 }
1340
1341 #ifdef _SYSCALL32_IMPL
1342 void
1343 prgetaction32(proc_t *p, user_t *up, uint_t sig, struct sigaction32 *sp)
1344 {
1345 int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
1346
1347 bzero(sp, sizeof (*sp));
1348
1349 if (sig != 0 && (unsigned)sig < nsig) {
1350 sp->sa_handler = (caddr32_t)(uintptr_t)up->u_signal[sig-1];
1351 prassignset(&sp->sa_mask, &up->u_sigmask[sig-1]);
1352 if (sigismember(&up->u_sigonstack, sig))
1353 sp->sa_flags |= SA_ONSTACK;
1354 if (sigismember(&up->u_sigresethand, sig))
1355 sp->sa_flags |= SA_RESETHAND;
1356 if (sigismember(&up->u_sigrestart, sig))
1357 sp->sa_flags |= SA_RESTART;
1358 if (sigismember(&p->p_siginfo, sig))
1359 sp->sa_flags |= SA_SIGINFO;
1360 if (sigismember(&up->u_signodefer, sig))
1361 sp->sa_flags |= SA_NODEFER;
1362 if (sig == SIGCLD) {
1363 if (p->p_flag & SNOWAIT)
1364 sp->sa_flags |= SA_NOCLDWAIT;
1365 if ((p->p_flag & SJCTL) == 0)
1366 sp->sa_flags |= SA_NOCLDSTOP;
1367 }
1368 }
1369 }
1370 #endif /* _SYSCALL32_IMPL */
1371
1372 /*
1373 * Count the number of segments in this process's address space.
1374 */
1375 int
1376 prnsegs(struct as *as, int reserved)
1377 {
1378 int n = 0;
1379 struct seg *seg;
1380
1381 ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1382
1383 for (seg = AS_SEGFIRST(as); seg != NULL; seg = AS_SEGNEXT(as, seg)) {
1384 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1385 caddr_t saddr, naddr;
1386 void *tmp = NULL;
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, &as->a_lock));
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 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1644 prot = pr_getprot(seg, reserved, &tmp,
1645 &saddr, &naddr, eaddr);
1646 if (saddr == naddr)
1647 continue;
1648
1649 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1650
1651 mp->pr_vaddr = (uintptr_t)saddr;
1652 mp->pr_size = naddr - saddr;
1653 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1654 mp->pr_mflags = 0;
1655 if (prot & PROT_READ)
1656 mp->pr_mflags |= MA_READ;
1657 if (prot & PROT_WRITE)
1658 mp->pr_mflags |= MA_WRITE;
1659 if (prot & PROT_EXEC)
1660 mp->pr_mflags |= MA_EXEC;
1661 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1662 mp->pr_mflags |= MA_SHARED;
1663 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1664 mp->pr_mflags |= MA_NORESERVE;
1665 if (seg->s_ops == &segspt_shmops ||
1666 (seg->s_ops == &segvn_ops &&
1667 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1668 mp->pr_mflags |= MA_ANON;
1669 if (seg == brkseg)
1670 mp->pr_mflags |= MA_BREAK;
1671 else if (seg == stkseg) {
1672 mp->pr_mflags |= MA_STACK;
1673 if (reserved) {
1674 size_t maxstack =
1675 ((size_t)p->p_stk_ctl +
1676 PAGEOFFSET) & PAGEMASK;
1677 mp->pr_vaddr =
1678 (uintptr_t)prgetstackbase(p) +
1679 p->p_stksize - maxstack;
1680 mp->pr_size = (uintptr_t)naddr -
1681 mp->pr_vaddr;
1682 }
1683 }
1684 if (seg->s_ops == &segspt_shmops)
1685 mp->pr_mflags |= MA_ISM | MA_SHM;
1686 mp->pr_pagesize = PAGESIZE;
1687
1688 /*
1689 * Manufacture a filename for the "object" directory.
1690 */
1691 vattr.va_mask = AT_FSID|AT_NODEID;
1692 if (seg->s_ops == &segvn_ops &&
1693 SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1694 vp != NULL && vp->v_type == VREG &&
1695 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1696 if (vp == p->p_exec)
1697 (void) strcpy(mp->pr_mapname, "a.out");
1698 else
1699 pr_object_name(mp->pr_mapname,
1700 vp, &vattr);
1701 }
1702
1703 /*
1704 * Get the SysV shared memory id, if any.
1705 */
1706 if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1707 (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1708 SHMID_NONE) {
1709 if (mp->pr_shmid == SHMID_FREE)
1710 mp->pr_shmid = -1;
1711
1712 mp->pr_mflags |= MA_SHM;
1713 } else {
1714 mp->pr_shmid = -1;
1715 }
1716 }
1717 ASSERT(tmp == NULL);
1718 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1719
1720 return (0);
1721 }
1722
1723 #ifdef _SYSCALL32_IMPL
1724 int
1725 prgetmap32(proc_t *p, int reserved, list_t *iolhead)
1726 {
1727 struct as *as = p->p_as;
1728 prmap32_t *mp;
1729 struct seg *seg;
1730 struct seg *brkseg, *stkseg;
1731 struct vnode *vp;
1732 struct vattr vattr;
1733 uint_t prot;
1734
1735 ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1736
1737 /*
1738 * Request an initial buffer size that doesn't waste memory
1739 * if the address space has only a small number of segments.
1740 */
1741 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
1742
1743 if ((seg = AS_SEGFIRST(as)) == NULL)
1744 return (0);
1745
1746 brkseg = break_seg(p);
1747 stkseg = as_segat(as, prgetstackbase(p));
1748
1749 do {
1750 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, reserved);
1751 caddr_t saddr, naddr;
1752 void *tmp = NULL;
1753
1754 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1755 prot = pr_getprot(seg, reserved, &tmp,
1756 &saddr, &naddr, eaddr);
1757 if (saddr == naddr)
1758 continue;
1759
1760 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
1761
1762 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
1763 mp->pr_size = (size32_t)(naddr - saddr);
1764 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1765 mp->pr_mflags = 0;
1766 if (prot & PROT_READ)
1767 mp->pr_mflags |= MA_READ;
1768 if (prot & PROT_WRITE)
1769 mp->pr_mflags |= MA_WRITE;
1770 if (prot & PROT_EXEC)
1771 mp->pr_mflags |= MA_EXEC;
1772 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1773 mp->pr_mflags |= MA_SHARED;
1774 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1775 mp->pr_mflags |= MA_NORESERVE;
1776 if (seg->s_ops == &segspt_shmops ||
1777 (seg->s_ops == &segvn_ops &&
1778 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1779 mp->pr_mflags |= MA_ANON;
1780 if (seg == brkseg)
1781 mp->pr_mflags |= MA_BREAK;
1782 else if (seg == stkseg) {
1783 mp->pr_mflags |= MA_STACK;
1784 if (reserved) {
1785 size_t maxstack =
1786 ((size_t)p->p_stk_ctl +
1787 PAGEOFFSET) & PAGEMASK;
1788 uintptr_t vaddr =
1789 (uintptr_t)prgetstackbase(p) +
1790 p->p_stksize - maxstack;
1791 mp->pr_vaddr = (caddr32_t)vaddr;
1792 mp->pr_size = (size32_t)
1793 ((uintptr_t)naddr - vaddr);
1794 }
1795 }
1796 if (seg->s_ops == &segspt_shmops)
1797 mp->pr_mflags |= MA_ISM | MA_SHM;
1798 mp->pr_pagesize = PAGESIZE;
1799
1800 /*
1801 * Manufacture a filename for the "object" directory.
1802 */
1803 vattr.va_mask = AT_FSID|AT_NODEID;
1804 if (seg->s_ops == &segvn_ops &&
1805 SEGOP_GETVP(seg, saddr, &vp) == 0 &&
1806 vp != NULL && vp->v_type == VREG &&
1807 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
1808 if (vp == p->p_exec)
1809 (void) strcpy(mp->pr_mapname, "a.out");
1810 else
1811 pr_object_name(mp->pr_mapname,
1812 vp, &vattr);
1813 }
1814
1815 /*
1816 * Get the SysV shared memory id, if any.
1817 */
1818 if ((mp->pr_mflags & MA_SHARED) && p->p_segacct &&
1819 (mp->pr_shmid = shmgetid(p, seg->s_base)) !=
1820 SHMID_NONE) {
1821 if (mp->pr_shmid == SHMID_FREE)
1822 mp->pr_shmid = -1;
1823
1824 mp->pr_mflags |= MA_SHM;
1825 } else {
1826 mp->pr_shmid = -1;
1827 }
1828 }
1829 ASSERT(tmp == NULL);
1830 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1831
1832 return (0);
1833 }
1834 #endif /* _SYSCALL32_IMPL */
1835
1836 /*
1837 * Return the size of the /proc page data file.
1838 */
1839 size_t
1840 prpdsize(struct as *as)
1841 {
1842 struct seg *seg;
1843 size_t size;
1844
1845 ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1846
1847 if ((seg = AS_SEGFIRST(as)) == NULL)
1848 return (0);
1849
1850 size = sizeof (prpageheader_t);
1851 do {
1852 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1853 caddr_t saddr, naddr;
1854 void *tmp = NULL;
1855 size_t npage;
1856
1857 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1858 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1859 if ((npage = (naddr - saddr) / PAGESIZE) != 0)
1860 size += sizeof (prasmap_t) + round8(npage);
1861 }
1862 ASSERT(tmp == NULL);
1863 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1864
1865 return (size);
1866 }
1867
1868 #ifdef _SYSCALL32_IMPL
1869 size_t
1870 prpdsize32(struct as *as)
1871 {
1872 struct seg *seg;
1873 size_t size;
1874
1875 ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
1876
1877 if ((seg = AS_SEGFIRST(as)) == NULL)
1878 return (0);
1879
1880 size = sizeof (prpageheader32_t);
1881 do {
1882 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1883 caddr_t saddr, naddr;
1884 void *tmp = NULL;
1885 size_t npage;
1886
1887 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1888 (void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1889 if ((npage = (naddr - saddr) / PAGESIZE) != 0)
1890 size += sizeof (prasmap32_t) + round8(npage);
1891 }
1892 ASSERT(tmp == NULL);
1893 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
1894
1895 return (size);
1896 }
1897 #endif /* _SYSCALL32_IMPL */
1898
1899 /*
1900 * Read page data information.
1901 */
1902 int
1903 prpdread(proc_t *p, uint_t hatid, struct uio *uiop)
1904 {
1905 struct as *as = p->p_as;
1906 caddr_t buf;
1907 size_t size;
1908 prpageheader_t *php;
1909 prasmap_t *pmp;
1910 struct seg *seg;
1911 int error;
1912
1913 again:
1914 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
1915
1916 if ((seg = AS_SEGFIRST(as)) == NULL) {
1917 AS_LOCK_EXIT(as, &as->a_lock);
1918 return (0);
1919 }
1920 size = prpdsize(as);
1921 if (uiop->uio_resid < size) {
1922 AS_LOCK_EXIT(as, &as->a_lock);
1923 return (E2BIG);
1924 }
1925
1926 buf = kmem_zalloc(size, KM_SLEEP);
1927 php = (prpageheader_t *)buf;
1928 pmp = (prasmap_t *)(buf + sizeof (prpageheader_t));
1929
1930 hrt2ts(gethrtime(), &php->pr_tstamp);
1931 php->pr_nmap = 0;
1932 php->pr_npage = 0;
1933 do {
1934 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
1935 caddr_t saddr, naddr;
1936 void *tmp = NULL;
1937
1938 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
1939 struct vnode *vp;
1940 struct vattr vattr;
1941 size_t len;
1942 size_t npage;
1943 uint_t prot;
1944 uintptr_t next;
1945
1946 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
1947 if ((len = (size_t)(naddr - saddr)) == 0)
1948 continue;
1949 npage = len / PAGESIZE;
1950 next = (uintptr_t)(pmp + 1) + round8(npage);
1951 /*
1952 * It's possible that the address space can change
1953 * subtlely even though we're holding as->a_lock
1954 * due to the nondeterminism of page_exists() in
1955 * the presence of asychronously flushed pages or
1956 * mapped files whose sizes are changing.
1957 * page_exists() may be called indirectly from
1958 * pr_getprot() by a SEGOP_INCORE() routine.
1959 * If this happens we need to make sure we don't
1960 * overrun the buffer whose size we computed based
1961 * on the initial iteration through the segments.
1962 * Once we've detected an overflow, we need to clean
1963 * up the temporary memory allocated in pr_getprot()
1964 * and retry. If there's a pending signal, we return
1965 * EINTR so that this thread can be dislodged if
1966 * a latent bug causes us to spin indefinitely.
1967 */
1968 if (next > (uintptr_t)buf + size) {
1969 pr_getprot_done(&tmp);
1970 AS_LOCK_EXIT(as, &as->a_lock);
1971
1972 kmem_free(buf, size);
1973
1974 if (ISSIG(curthread, JUSTLOOKING))
1975 return (EINTR);
1976
1977 goto again;
1978 }
1979
1980 php->pr_nmap++;
1981 php->pr_npage += npage;
1982 pmp->pr_vaddr = (uintptr_t)saddr;
1983 pmp->pr_npage = npage;
1984 pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
1985 pmp->pr_mflags = 0;
1986 if (prot & PROT_READ)
1987 pmp->pr_mflags |= MA_READ;
1988 if (prot & PROT_WRITE)
1989 pmp->pr_mflags |= MA_WRITE;
1990 if (prot & PROT_EXEC)
1991 pmp->pr_mflags |= MA_EXEC;
1992 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
1993 pmp->pr_mflags |= MA_SHARED;
1994 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
1995 pmp->pr_mflags |= MA_NORESERVE;
1996 if (seg->s_ops == &segspt_shmops ||
1997 (seg->s_ops == &segvn_ops &&
1998 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
1999 pmp->pr_mflags |= MA_ANON;
2000 if (seg->s_ops == &segspt_shmops)
2001 pmp->pr_mflags |= MA_ISM | MA_SHM;
2002 pmp->pr_pagesize = PAGESIZE;
2003 /*
2004 * Manufacture a filename for the "object" directory.
2005 */
2006 vattr.va_mask = AT_FSID|AT_NODEID;
2007 if (seg->s_ops == &segvn_ops &&
2008 SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2009 vp != NULL && vp->v_type == VREG &&
2010 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2011 if (vp == p->p_exec)
2012 (void) strcpy(pmp->pr_mapname, "a.out");
2013 else
2014 pr_object_name(pmp->pr_mapname,
2015 vp, &vattr);
2016 }
2017
2018 /*
2019 * Get the SysV shared memory id, if any.
2020 */
2021 if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2022 (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2023 SHMID_NONE) {
2024 if (pmp->pr_shmid == SHMID_FREE)
2025 pmp->pr_shmid = -1;
2026
2027 pmp->pr_mflags |= MA_SHM;
2028 } else {
2029 pmp->pr_shmid = -1;
2030 }
2031
2032 hat_getstat(as, saddr, len, hatid,
2033 (char *)(pmp + 1), HAT_SYNC_ZERORM);
2034 pmp = (prasmap_t *)next;
2035 }
2036 ASSERT(tmp == NULL);
2037 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2038
2039 AS_LOCK_EXIT(as, &as->a_lock);
2040
2041 ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2042 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2043 kmem_free(buf, size);
2044
2045 return (error);
2046 }
2047
2048 #ifdef _SYSCALL32_IMPL
2049 int
2050 prpdread32(proc_t *p, uint_t hatid, struct uio *uiop)
2051 {
2052 struct as *as = p->p_as;
2053 caddr_t buf;
2054 size_t size;
2055 prpageheader32_t *php;
2056 prasmap32_t *pmp;
2057 struct seg *seg;
2058 int error;
2059
2060 again:
2061 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
2062
2063 if ((seg = AS_SEGFIRST(as)) == NULL) {
2064 AS_LOCK_EXIT(as, &as->a_lock);
2065 return (0);
2066 }
2067 size = prpdsize32(as);
2068 if (uiop->uio_resid < size) {
2069 AS_LOCK_EXIT(as, &as->a_lock);
2070 return (E2BIG);
2071 }
2072
2073 buf = kmem_zalloc(size, KM_SLEEP);
2074 php = (prpageheader32_t *)buf;
2075 pmp = (prasmap32_t *)(buf + sizeof (prpageheader32_t));
2076
2077 hrt2ts32(gethrtime(), &php->pr_tstamp);
2078 php->pr_nmap = 0;
2079 php->pr_npage = 0;
2080 do {
2081 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
2082 caddr_t saddr, naddr;
2083 void *tmp = NULL;
2084
2085 for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
2086 struct vnode *vp;
2087 struct vattr vattr;
2088 size_t len;
2089 size_t npage;
2090 uint_t prot;
2091 uintptr_t next;
2092
2093 prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
2094 if ((len = (size_t)(naddr - saddr)) == 0)
2095 continue;
2096 npage = len / PAGESIZE;
2097 next = (uintptr_t)(pmp + 1) + round8(npage);
2098 /*
2099 * It's possible that the address space can change
2100 * subtlely even though we're holding as->a_lock
2101 * due to the nondeterminism of page_exists() in
2102 * the presence of asychronously flushed pages or
2103 * mapped files whose sizes are changing.
2104 * page_exists() may be called indirectly from
2105 * pr_getprot() by a SEGOP_INCORE() routine.
2106 * If this happens we need to make sure we don't
2107 * overrun the buffer whose size we computed based
2108 * on the initial iteration through the segments.
2109 * Once we've detected an overflow, we need to clean
2110 * up the temporary memory allocated in pr_getprot()
2111 * and retry. If there's a pending signal, we return
2112 * EINTR so that this thread can be dislodged if
2113 * a latent bug causes us to spin indefinitely.
2114 */
2115 if (next > (uintptr_t)buf + size) {
2116 pr_getprot_done(&tmp);
2117 AS_LOCK_EXIT(as, &as->a_lock);
2118
2119 kmem_free(buf, size);
2120
2121 if (ISSIG(curthread, JUSTLOOKING))
2122 return (EINTR);
2123
2124 goto again;
2125 }
2126
2127 php->pr_nmap++;
2128 php->pr_npage += npage;
2129 pmp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
2130 pmp->pr_npage = (size32_t)npage;
2131 pmp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
2132 pmp->pr_mflags = 0;
2133 if (prot & PROT_READ)
2134 pmp->pr_mflags |= MA_READ;
2135 if (prot & PROT_WRITE)
2136 pmp->pr_mflags |= MA_WRITE;
2137 if (prot & PROT_EXEC)
2138 pmp->pr_mflags |= MA_EXEC;
2139 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
2140 pmp->pr_mflags |= MA_SHARED;
2141 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
2142 pmp->pr_mflags |= MA_NORESERVE;
2143 if (seg->s_ops == &segspt_shmops ||
2144 (seg->s_ops == &segvn_ops &&
2145 (SEGOP_GETVP(seg, saddr, &vp) != 0 || vp == NULL)))
2146 pmp->pr_mflags |= MA_ANON;
2147 if (seg->s_ops == &segspt_shmops)
2148 pmp->pr_mflags |= MA_ISM | MA_SHM;
2149 pmp->pr_pagesize = PAGESIZE;
2150 /*
2151 * Manufacture a filename for the "object" directory.
2152 */
2153 vattr.va_mask = AT_FSID|AT_NODEID;
2154 if (seg->s_ops == &segvn_ops &&
2155 SEGOP_GETVP(seg, saddr, &vp) == 0 &&
2156 vp != NULL && vp->v_type == VREG &&
2157 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
2158 if (vp == p->p_exec)
2159 (void) strcpy(pmp->pr_mapname, "a.out");
2160 else
2161 pr_object_name(pmp->pr_mapname,
2162 vp, &vattr);
2163 }
2164
2165 /*
2166 * Get the SysV shared memory id, if any.
2167 */
2168 if ((pmp->pr_mflags & MA_SHARED) && p->p_segacct &&
2169 (pmp->pr_shmid = shmgetid(p, seg->s_base)) !=
2170 SHMID_NONE) {
2171 if (pmp->pr_shmid == SHMID_FREE)
2172 pmp->pr_shmid = -1;
2173
2174 pmp->pr_mflags |= MA_SHM;
2175 } else {
2176 pmp->pr_shmid = -1;
2177 }
2178
2179 hat_getstat(as, saddr, len, hatid,
2180 (char *)(pmp + 1), HAT_SYNC_ZERORM);
2181 pmp = (prasmap32_t *)next;
2182 }
2183 ASSERT(tmp == NULL);
2184 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
2185
2186 AS_LOCK_EXIT(as, &as->a_lock);
2187
2188 ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
2189 error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
2190 kmem_free(buf, size);
2191
2192 return (error);
2193 }
2194 #endif /* _SYSCALL32_IMPL */
2195
2196 ushort_t
2197 prgetpctcpu(uint64_t pct)
2198 {
2199 /*
2200 * The value returned will be relevant in the zone of the examiner,
2201 * which may not be the same as the zone which performed the procfs
2202 * mount.
2203 */
2204 int nonline = zone_ncpus_online_get(curproc->p_zone);
2205
2206 /*
2207 * Prorate over online cpus so we don't exceed 100%
2208 */
2209 if (nonline > 1)
2210 pct /= nonline;
2211 pct >>= 16; /* convert to 16-bit scaled integer */
2212 if (pct > 0x8000) /* might happen, due to rounding */
2213 pct = 0x8000;
2214 return ((ushort_t)pct);
2215 }
2216
2217 /*
2218 * Return information used by ps(1).
2219 */
2220 void
2221 prgetpsinfo(proc_t *p, psinfo_t *psp)
2222 {
2223 kthread_t *t;
2224 struct cred *cred;
2225 hrtime_t hrutime, hrstime;
2226
2227 ASSERT(MUTEX_HELD(&p->p_lock));
2228
2229 if ((t = prchoose(p)) == NULL) /* returns locked thread */
2230 bzero(psp, sizeof (*psp));
2231 else {
2232 thread_unlock(t);
2233 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2234 }
2235
2236 /*
2237 * only export SSYS and SMSACCT; everything else is off-limits to
2238 * userland apps.
2239 */
2240 psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2241 psp->pr_nlwp = p->p_lwpcnt;
2242 psp->pr_nzomb = p->p_zombcnt;
2243 mutex_enter(&p->p_crlock);
2244 cred = p->p_cred;
2245 psp->pr_uid = crgetruid(cred);
2246 psp->pr_euid = crgetuid(cred);
2247 psp->pr_gid = crgetrgid(cred);
2248 psp->pr_egid = crgetgid(cred);
2249 mutex_exit(&p->p_crlock);
2250 psp->pr_pid = p->p_pid;
2251 if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
2252 (p->p_flag & SZONETOP)) {
2253 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
2254 /*
2255 * Inside local zones, fake zsched's pid as parent pids for
2256 * processes which reference processes outside of the zone.
2257 */
2258 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
2259 } else {
2260 psp->pr_ppid = p->p_ppid;
2261 }
2262 psp->pr_pgid = p->p_pgrp;
2263 psp->pr_sid = p->p_sessp->s_sid;
2264 psp->pr_taskid = p->p_task->tk_tkid;
2265 psp->pr_projid = p->p_task->tk_proj->kpj_id;
2266 psp->pr_poolid = p->p_pool->pool_id;
2267 psp->pr_zoneid = p->p_zone->zone_id;
2268 if ((psp->pr_contract = PRCTID(p)) == 0)
2269 psp->pr_contract = -1;
2270 psp->pr_addr = (uintptr_t)prgetpsaddr(p);
2271 switch (p->p_model) {
2272 case DATAMODEL_ILP32:
2273 psp->pr_dmodel = PR_MODEL_ILP32;
2274 break;
2275 case DATAMODEL_LP64:
2276 psp->pr_dmodel = PR_MODEL_LP64;
2277 break;
2278 }
2279 hrutime = mstate_aggr_state(p, LMS_USER);
2280 hrstime = mstate_aggr_state(p, LMS_SYSTEM);
2281 hrt2ts((hrutime + hrstime), &psp->pr_time);
2282 TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime);
2283
2284 if (t == NULL) {
2285 int wcode = p->p_wcode; /* must be atomic read */
2286
2287 if (wcode)
2288 psp->pr_wstat = wstat(wcode, p->p_wdata);
2289 psp->pr_ttydev = PRNODEV;
2290 psp->pr_lwp.pr_state = SZOMB;
2291 psp->pr_lwp.pr_sname = 'Z';
2292 psp->pr_lwp.pr_bindpro = PBIND_NONE;
2293 psp->pr_lwp.pr_bindpset = PS_NONE;
2294 } else {
2295 user_t *up = PTOU(p);
2296 struct as *as;
2297 dev_t d;
2298 extern dev_t rwsconsdev, rconsdev, uconsdev;
2299
2300 d = cttydev(p);
2301 /*
2302 * If the controlling terminal is the real
2303 * or workstation console device, map to what the
2304 * user thinks is the console device. Handle case when
2305 * rwsconsdev or rconsdev is set to NODEV for Starfire.
2306 */
2307 if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
2308 d = uconsdev;
2309 psp->pr_ttydev = (d == NODEV) ? PRNODEV : d;
2310 psp->pr_start = up->u_start;
2311 bcopy(up->u_comm, psp->pr_fname,
2312 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2313 bcopy(up->u_psargs, psp->pr_psargs,
2314 MIN(PRARGSZ-1, PSARGSZ));
2315 psp->pr_argc = up->u_argc;
2316 psp->pr_argv = up->u_argv;
2317 psp->pr_envp = up->u_envp;
2318
2319 /* get the chosen lwp's lwpsinfo */
2320 prgetlwpsinfo(t, &psp->pr_lwp);
2321
2322 /* compute %cpu for the process */
2323 if (p->p_lwpcnt == 1)
2324 psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
2325 else {
2326 uint64_t pct = 0;
2327 hrtime_t cur_time = gethrtime_unscaled();
2328
2329 t = p->p_tlist;
2330 do {
2331 pct += cpu_update_pct(t, cur_time);
2332 } while ((t = t->t_forw) != p->p_tlist);
2333
2334 psp->pr_pctcpu = prgetpctcpu(pct);
2335 }
2336 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
2337 psp->pr_size = 0;
2338 psp->pr_rssize = 0;
2339 } else {
2340 mutex_exit(&p->p_lock);
2341 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
2342 psp->pr_size = btopr(as->a_resvsize) *
2343 (PAGESIZE / 1024);
2344 psp->pr_rssize = rm_asrss(as) * (PAGESIZE / 1024);
2345 psp->pr_pctmem = rm_pctmemory(as);
2346 AS_LOCK_EXIT(as, &as->a_lock);
2347 mutex_enter(&p->p_lock);
2348 }
2349 }
2350 }
2351
2352 #ifdef _SYSCALL32_IMPL
2353 void
2354 prgetpsinfo32(proc_t *p, psinfo32_t *psp)
2355 {
2356 kthread_t *t;
2357 struct cred *cred;
2358 hrtime_t hrutime, hrstime;
2359
2360 ASSERT(MUTEX_HELD(&p->p_lock));
2361
2362 if ((t = prchoose(p)) == NULL) /* returns locked thread */
2363 bzero(psp, sizeof (*psp));
2364 else {
2365 thread_unlock(t);
2366 bzero(psp, sizeof (*psp) - sizeof (psp->pr_lwp));
2367 }
2368
2369 /*
2370 * only export SSYS and SMSACCT; everything else is off-limits to
2371 * userland apps.
2372 */
2373 psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
2374 psp->pr_nlwp = p->p_lwpcnt;
2375 psp->pr_nzomb = p->p_zombcnt;
2376 mutex_enter(&p->p_crlock);
2377 cred = p->p_cred;
2378 psp->pr_uid = crgetruid(cred);
2379 psp->pr_euid = crgetuid(cred);
2380 psp->pr_gid = crgetrgid(cred);
2381 psp->pr_egid = crgetgid(cred);
2382 mutex_exit(&p->p_crlock);
2383 psp->pr_pid = p->p_pid;
2384 if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
2385 (p->p_flag & SZONETOP)) {
2386 ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
2387 /*
2388 * Inside local zones, fake zsched's pid as parent pids for
2389 * processes which reference processes outside of the zone.
2390 */
2391 psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
2392 } else {
2393 psp->pr_ppid = p->p_ppid;
2394 }
2395 psp->pr_pgid = p->p_pgrp;
2396 psp->pr_sid = p->p_sessp->s_sid;
2397 psp->pr_taskid = p->p_task->tk_tkid;
2398 psp->pr_projid = p->p_task->tk_proj->kpj_id;
2399 psp->pr_poolid = p->p_pool->pool_id;
2400 psp->pr_zoneid = p->p_zone->zone_id;
2401 if ((psp->pr_contract = PRCTID(p)) == 0)
2402 psp->pr_contract = -1;
2403 psp->pr_addr = 0; /* cannot represent 64-bit addr in 32 bits */
2404 switch (p->p_model) {
2405 case DATAMODEL_ILP32:
2406 psp->pr_dmodel = PR_MODEL_ILP32;
2407 break;
2408 case DATAMODEL_LP64:
2409 psp->pr_dmodel = PR_MODEL_LP64;
2410 break;
2411 }
2412 hrutime = mstate_aggr_state(p, LMS_USER);
2413 hrstime = mstate_aggr_state(p, LMS_SYSTEM);
2414 hrt2ts32(hrutime + hrstime, &psp->pr_time);
2415 TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime);
2416
2417 if (t == NULL) {
2418 extern int wstat(int, int); /* needs a header file */
2419 int wcode = p->p_wcode; /* must be atomic read */
2420
2421 if (wcode)
2422 psp->pr_wstat = wstat(wcode, p->p_wdata);
2423 psp->pr_ttydev = PRNODEV32;
2424 psp->pr_lwp.pr_state = SZOMB;
2425 psp->pr_lwp.pr_sname = 'Z';
2426 } else {
2427 user_t *up = PTOU(p);
2428 struct as *as;
2429 dev_t d;
2430 extern dev_t rwsconsdev, rconsdev, uconsdev;
2431
2432 d = cttydev(p);
2433 /*
2434 * If the controlling terminal is the real
2435 * or workstation console device, map to what the
2436 * user thinks is the console device. Handle case when
2437 * rwsconsdev or rconsdev is set to NODEV for Starfire.
2438 */
2439 if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
2440 d = uconsdev;
2441 (void) cmpldev(&psp->pr_ttydev, d);
2442 TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start);
2443 bcopy(up->u_comm, psp->pr_fname,
2444 MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
2445 bcopy(up->u_psargs, psp->pr_psargs,
2446 MIN(PRARGSZ-1, PSARGSZ));
2447 psp->pr_argc = up->u_argc;
2448 psp->pr_argv = (caddr32_t)up->u_argv;
2449 psp->pr_envp = (caddr32_t)up->u_envp;
2450
2451 /* get the chosen lwp's lwpsinfo */
2452 prgetlwpsinfo32(t, &psp->pr_lwp);
2453
2454 /* compute %cpu for the process */
2455 if (p->p_lwpcnt == 1)
2456 psp->pr_pctcpu = psp->pr_lwp.pr_pctcpu;
2457 else {
2458 uint64_t pct = 0;
2459 hrtime_t cur_time;
2460
2461 t = p->p_tlist;
2462 cur_time = gethrtime_unscaled();
2463 do {
2464 pct += cpu_update_pct(t, cur_time);
2465 } while ((t = t->t_forw) != p->p_tlist);
2466
2467 psp->pr_pctcpu = prgetpctcpu(pct);
2468 }
2469 if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
2470 psp->pr_size = 0;
2471 psp->pr_rssize = 0;
2472 } else {
2473 mutex_exit(&p->p_lock);
2474 AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
2475 psp->pr_size = (size32_t)
2476 (btopr(as->a_resvsize) * (PAGESIZE / 1024));
2477 psp->pr_rssize = (size32_t)
2478 (rm_asrss(as) * (PAGESIZE / 1024));
2479 psp->pr_pctmem = rm_pctmemory(as);
2480 AS_LOCK_EXIT(as, &as->a_lock);
2481 mutex_enter(&p->p_lock);
2482 }
2483 }
2484
2485 /*
2486 * If we are looking at an LP64 process, zero out
2487 * the fields that cannot be represented in ILP32.
2488 */
2489 if (p->p_model != DATAMODEL_ILP32) {
2490 psp->pr_size = 0;
2491 psp->pr_rssize = 0;
2492 psp->pr_argv = 0;
2493 psp->pr_envp = 0;
2494 }
2495 }
2496
2497 #endif /* _SYSCALL32_IMPL */
2498
2499 void
2500 prgetlwpsinfo(kthread_t *t, lwpsinfo_t *psp)
2501 {
2502 klwp_t *lwp = ttolwp(t);
2503 sobj_ops_t *sobj;
2504 char c, state;
2505 uint64_t pct;
2506 int retval, niceval;
2507 hrtime_t hrutime, hrstime;
2508
2509 ASSERT(MUTEX_HELD(&ttoproc(t)->p_lock));
2510
2511 bzero(psp, sizeof (*psp));
2512
2513 psp->pr_flag = 0; /* lwpsinfo_t.pr_flag is deprecated */
2514 psp->pr_lwpid = t->t_tid;
2515 psp->pr_addr = (uintptr_t)t;
2516 psp->pr_wchan = (uintptr_t)t->t_wchan;
2517
2518 /* map the thread state enum into a process state enum */
2519 state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
2520 switch (state) {
2521 case TS_SLEEP: state = SSLEEP; c = 'S'; break;
2522 case TS_RUN: state = SRUN; c = 'R'; break;
2523 case TS_ONPROC: state = SONPROC; c = 'O'; break;
2524 case TS_ZOMB: state = SZOMB; c = 'Z'; break;
2525 case TS_STOPPED: state = SSTOP; c = 'T'; break;
2526 case TS_WAIT: state = SWAIT; c = 'W'; break;
2527 default: state = 0; c = '?'; break;
2528 }
2529 psp->pr_state = state;
2530 psp->pr_sname = c;
2531 if ((sobj = t->t_sobj_ops) != NULL)
2532 psp->pr_stype = SOBJ_TYPE(sobj);
2533 retval = CL_DONICE(t, NULL, 0, &niceval);
2534 if (retval == 0) {
2535 psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
2536 psp->pr_nice = niceval + NZERO;
2537 }
2538 psp->pr_syscall = t->t_sysnum;
2539 psp->pr_pri = t->t_pri;
2540 psp->pr_start.tv_sec = t->t_start;
2541 psp->pr_start.tv_nsec = 0L;
2542 hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
2543 scalehrtime(&hrutime);
2544 hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
2545 lwp->lwp_mstate.ms_acct[LMS_TRAP];
2546 scalehrtime(&hrstime);
2547 hrt2ts(hrutime + hrstime, &psp->pr_time);
2548 /* compute %cpu for the lwp */
2549 pct = cpu_update_pct(t, gethrtime_unscaled());
2550 psp->pr_pctcpu = prgetpctcpu(pct);
2551 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */
2552 if (psp->pr_cpu > 99)
2553 psp->pr_cpu = 99;
2554
2555 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
2556 sizeof (psp->pr_clname) - 1);
2557 bzero(psp->pr_name, sizeof (psp->pr_name)); /* XXX ??? */
2558 psp->pr_onpro = t->t_cpu->cpu_id;
2559 psp->pr_bindpro = t->t_bind_cpu;
2560 psp->pr_bindpset = t->t_bind_pset;
2561 psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
2562 }
2563
2564 #ifdef _SYSCALL32_IMPL
2565 void
2566 prgetlwpsinfo32(kthread_t *t, lwpsinfo32_t *psp)
2567 {
2568 proc_t *p = ttoproc(t);
2569 klwp_t *lwp = ttolwp(t);
2570 sobj_ops_t *sobj;
2571 char c, state;
2572 uint64_t pct;
2573 int retval, niceval;
2574 hrtime_t hrutime, hrstime;
2575
2576 ASSERT(MUTEX_HELD(&p->p_lock));
2577
2578 bzero(psp, sizeof (*psp));
2579
2580 psp->pr_flag = 0; /* lwpsinfo_t.pr_flag is deprecated */
2581 psp->pr_lwpid = t->t_tid;
2582 psp->pr_addr = 0; /* cannot represent 64-bit addr in 32 bits */
2583 psp->pr_wchan = 0; /* cannot represent 64-bit addr in 32 bits */
2584
2585 /* map the thread state enum into a process state enum */
2586 state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
2587 switch (state) {
2588 case TS_SLEEP: state = SSLEEP; c = 'S'; break;
2589 case TS_RUN: state = SRUN; c = 'R'; break;
2590 case TS_ONPROC: state = SONPROC; c = 'O'; break;
2591 case TS_ZOMB: state = SZOMB; c = 'Z'; break;
2592 case TS_STOPPED: state = SSTOP; c = 'T'; break;
2593 case TS_WAIT: state = SWAIT; c = 'W'; break;
2594 default: state = 0; c = '?'; break;
2595 }
2596 psp->pr_state = state;
2597 psp->pr_sname = c;
2598 if ((sobj = t->t_sobj_ops) != NULL)
2599 psp->pr_stype = SOBJ_TYPE(sobj);
2600 retval = CL_DONICE(t, NULL, 0, &niceval);
2601 if (retval == 0) {
2602 psp->pr_oldpri = v.v_maxsyspri - t->t_pri;
2603 psp->pr_nice = niceval + NZERO;
2604 } else {
2605 psp->pr_oldpri = 0;
2606 psp->pr_nice = 0;
2607 }
2608 psp->pr_syscall = t->t_sysnum;
2609 psp->pr_pri = t->t_pri;
2610 psp->pr_start.tv_sec = (time32_t)t->t_start;
2611 psp->pr_start.tv_nsec = 0L;
2612 hrutime = lwp->lwp_mstate.ms_acct[LMS_USER];
2613 scalehrtime(&hrutime);
2614 hrstime = lwp->lwp_mstate.ms_acct[LMS_SYSTEM] +
2615 lwp->lwp_mstate.ms_acct[LMS_TRAP];
2616 scalehrtime(&hrstime);
2617 hrt2ts32(hrutime + hrstime, &psp->pr_time);
2618 /* compute %cpu for the lwp */
2619 pct = cpu_update_pct(t, gethrtime_unscaled());
2620 psp->pr_pctcpu = prgetpctcpu(pct);
2621 psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */
2622 if (psp->pr_cpu > 99)
2623 psp->pr_cpu = 99;
2624
2625 (void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
2626 sizeof (psp->pr_clname) - 1);
2627 bzero(psp->pr_name, sizeof (psp->pr_name)); /* XXX ??? */
2628 psp->pr_onpro = t->t_cpu->cpu_id;
2629 psp->pr_bindpro = t->t_bind_cpu;
2630 psp->pr_bindpset = t->t_bind_pset;
2631 psp->pr_lgrp = t->t_lpl->lpl_lgrpid;
2632 }
2633 #endif /* _SYSCALL32_IMPL */
2634
2635 #ifdef _SYSCALL32_IMPL
2636
2637 #define PR_COPY_FIELD(s, d, field) d->field = s->field
2638
2639 #define PR_COPY_FIELD_ILP32(s, d, field) \
2640 if (s->pr_dmodel == PR_MODEL_ILP32) { \
2641 d->field = s->field; \
2642 }
2643
2644 #define PR_COPY_TIMESPEC(s, d, field) \
2645 TIMESPEC_TO_TIMESPEC32(&d->field, &s->field);
2646
2647 #define PR_COPY_BUF(s, d, field) \
2648 bcopy(s->field, d->field, sizeof (d->field));
2649
2650 #define PR_IGNORE_FIELD(s, d, field)
2651
2652 void
2653 lwpsinfo_kto32(const struct lwpsinfo *src, struct lwpsinfo32 *dest)
2654 {
2655 bzero(dest, sizeof (*dest));
2656
2657 PR_COPY_FIELD(src, dest, pr_flag);
2658 PR_COPY_FIELD(src, dest, pr_lwpid);
2659 PR_IGNORE_FIELD(src, dest, pr_addr);
2660 PR_IGNORE_FIELD(src, dest, pr_wchan);
2661 PR_COPY_FIELD(src, dest, pr_stype);
2662 PR_COPY_FIELD(src, dest, pr_state);
2663 PR_COPY_FIELD(src, dest, pr_sname);
2664 PR_COPY_FIELD(src, dest, pr_nice);
2665 PR_COPY_FIELD(src, dest, pr_syscall);
2666 PR_COPY_FIELD(src, dest, pr_oldpri);
2667 PR_COPY_FIELD(src, dest, pr_cpu);
2668 PR_COPY_FIELD(src, dest, pr_pri);
2669 PR_COPY_FIELD(src, dest, pr_pctcpu);
2670 PR_COPY_TIMESPEC(src, dest, pr_start);
2671 PR_COPY_BUF(src, dest, pr_clname);
2672 PR_COPY_BUF(src, dest, pr_name);
2673 PR_COPY_FIELD(src, dest, pr_onpro);
2674 PR_COPY_FIELD(src, dest, pr_bindpro);
2675 PR_COPY_FIELD(src, dest, pr_bindpset);
2676 PR_COPY_FIELD(src, dest, pr_lgrp);
2677 }
2678
2679 void
2680 psinfo_kto32(const struct psinfo *src, struct psinfo32 *dest)
2681 {
2682 bzero(dest, sizeof (*dest));
2683
2684 PR_COPY_FIELD(src, dest, pr_flag);
2685 PR_COPY_FIELD(src, dest, pr_nlwp);
2686 PR_COPY_FIELD(src, dest, pr_pid);
2687 PR_COPY_FIELD(src, dest, pr_ppid);
2688 PR_COPY_FIELD(src, dest, pr_pgid);
2689 PR_COPY_FIELD(src, dest, pr_sid);
2690 PR_COPY_FIELD(src, dest, pr_uid);
2691 PR_COPY_FIELD(src, dest, pr_euid);
2692 PR_COPY_FIELD(src, dest, pr_gid);
2693 PR_COPY_FIELD(src, dest, pr_egid);
2694 PR_IGNORE_FIELD(src, dest, pr_addr);
2695 PR_COPY_FIELD_ILP32(src, dest, pr_size);
2696 PR_COPY_FIELD_ILP32(src, dest, pr_rssize);
2697 PR_COPY_FIELD(src, dest, pr_ttydev);
2698 PR_COPY_FIELD(src, dest, pr_pctcpu);
2699 PR_COPY_FIELD(src, dest, pr_pctmem);
2700 PR_COPY_TIMESPEC(src, dest, pr_start);
2701 PR_COPY_TIMESPEC(src, dest, pr_time);
2702 PR_COPY_TIMESPEC(src, dest, pr_ctime);
2703 PR_COPY_BUF(src, dest, pr_fname);
2704 PR_COPY_BUF(src, dest, pr_psargs);
2705 PR_COPY_FIELD(src, dest, pr_wstat);
2706 PR_COPY_FIELD(src, dest, pr_argc);
2707 PR_COPY_FIELD_ILP32(src, dest, pr_argv);
2708 PR_COPY_FIELD_ILP32(src, dest, pr_envp);
2709 PR_COPY_FIELD(src, dest, pr_dmodel);
2710 PR_COPY_FIELD(src, dest, pr_taskid);
2711 PR_COPY_FIELD(src, dest, pr_projid);
2712 PR_COPY_FIELD(src, dest, pr_nzomb);
2713 PR_COPY_FIELD(src, dest, pr_poolid);
2714 PR_COPY_FIELD(src, dest, pr_contract);
2715 PR_COPY_FIELD(src, dest, pr_poolid);
2716 PR_COPY_FIELD(src, dest, pr_poolid);
2717
2718 lwpsinfo_kto32(&src->pr_lwp, &dest->pr_lwp);
2719 }
2720
2721 #undef PR_COPY_FIELD
2722 #undef PR_COPY_FIELD_ILP32
2723 #undef PR_COPY_TIMESPEC
2724 #undef PR_COPY_BUF
2725 #undef PR_IGNORE_FIELD
2726
2727 #endif /* _SYSCALL32_IMPL */
2728
2729 /*
2730 * This used to get called when microstate accounting was disabled but
2731 * microstate information was requested. Since Microstate accounting is on
2732 * regardless of the proc flags, this simply makes it appear to procfs that
2733 * microstate accounting is on. This is relatively meaningless since you
2734 * can't turn it off, but this is here for the sake of appearances.
2735 */
2736
2737 /*ARGSUSED*/
2738 void
2739 estimate_msacct(kthread_t *t, hrtime_t curtime)
2740 {
2741 proc_t *p;
2742
2743 if (t == NULL)
2744 return;
2745
2746 p = ttoproc(t);
2747 ASSERT(MUTEX_HELD(&p->p_lock));
2748
2749 /*
2750 * A system process (p0) could be referenced if the thread is
2751 * in the process of exiting. Don't turn on microstate accounting
2752 * in that case.
2753 */
2754 if (p->p_flag & SSYS)
2755 return;
2756
2757 /*
2758 * Loop through all the LWPs (kernel threads) in the process.
2759 */
2760 t = p->p_tlist;
2761 do {
2762 t->t_proc_flag |= TP_MSACCT;
2763 } while ((t = t->t_forw) != p->p_tlist);
2764
2765 p->p_flag |= SMSACCT; /* set process-wide MSACCT */
2766 }
2767
2768 /*
2769 * It's not really possible to disable microstate accounting anymore.
2770 * However, this routine simply turns off the ms accounting flags in a process
2771 * This way procfs can still pretend to turn microstate accounting on and
2772 * off for a process, but it actually doesn't do anything. This is
2773 * a neutered form of preemptive idiot-proofing.
2774 */
2775 void
2776 disable_msacct(proc_t *p)
2777 {
2778 kthread_t *t;
2779
2780 ASSERT(MUTEX_HELD(&p->p_lock));
2781
2782 p->p_flag &= ~SMSACCT; /* clear process-wide MSACCT */
2783 /*
2784 * Loop through all the LWPs (kernel threads) in the process.
2785 */
2786 if ((t = p->p_tlist) != NULL) {
2787 do {
2788 /* clear per-thread flag */
2789 t->t_proc_flag &= ~TP_MSACCT;
2790 } while ((t = t->t_forw) != p->p_tlist);
2791 }
2792 }
2793
2794 /*
2795 * Return resource usage information.
2796 */
2797 void
2798 prgetusage(kthread_t *t, prhusage_t *pup)
2799 {
2800 klwp_t *lwp = ttolwp(t);
2801 hrtime_t *mstimep;
2802 struct mstate *ms = &lwp->lwp_mstate;
2803 int state;
2804 int i;
2805 hrtime_t curtime;
2806 hrtime_t waitrq;
2807 hrtime_t tmp1;
2808
2809 curtime = gethrtime_unscaled();
2810
2811 pup->pr_lwpid = t->t_tid;
2812 pup->pr_count = 1;
2813 pup->pr_create = ms->ms_start;
2814 pup->pr_term = ms->ms_term;
2815 scalehrtime(&pup->pr_create);
2816 scalehrtime(&pup->pr_term);
2817 if (ms->ms_term == 0) {
2818 pup->pr_rtime = curtime - ms->ms_start;
2819 scalehrtime(&pup->pr_rtime);
2820 } else {
2821 pup->pr_rtime = ms->ms_term - ms->ms_start;
2822 scalehrtime(&pup->pr_rtime);
2823 }
2824
2825
2826 pup->pr_utime = ms->ms_acct[LMS_USER];
2827 pup->pr_stime = ms->ms_acct[LMS_SYSTEM];
2828 pup->pr_ttime = ms->ms_acct[LMS_TRAP];
2829 pup->pr_tftime = ms->ms_acct[LMS_TFAULT];
2830 pup->pr_dftime = ms->ms_acct[LMS_DFAULT];
2831 pup->pr_kftime = ms->ms_acct[LMS_KFAULT];
2832 pup->pr_ltime = ms->ms_acct[LMS_USER_LOCK];
2833 pup->pr_slptime = ms->ms_acct[LMS_SLEEP];
2834 pup->pr_wtime = ms->ms_acct[LMS_WAIT_CPU];
2835 pup->pr_stoptime = ms->ms_acct[LMS_STOPPED];
2836
2837 prscaleusage(pup);
2838
2839 /*
2840 * Adjust for time waiting in the dispatcher queue.
2841 */
2842 waitrq = t->t_waitrq; /* hopefully atomic */
2843 if (waitrq != 0) {
2844 if (waitrq > curtime) {
2845 curtime = gethrtime_unscaled();
2846 }
2847 tmp1 = curtime - waitrq;
2848 scalehrtime(&tmp1);
2849 pup->pr_wtime += tmp1;
2850 curtime = waitrq;
2851 }
2852
2853 /*
2854 * Adjust for time spent in current microstate.
2855 */
2856 if (ms->ms_state_start > curtime) {
2857 curtime = gethrtime_unscaled();
2858 }
2859
2860 i = 0;
2861 do {
2862 switch (state = t->t_mstate) {
2863 case LMS_SLEEP:
2864 /*
2865 * Update the timer for the current sleep state.
2866 */
2867 switch (state = ms->ms_prev) {
2868 case LMS_TFAULT:
2869 case LMS_DFAULT:
2870 case LMS_KFAULT:
2871 case LMS_USER_LOCK:
2872 break;
2873 default:
2874 state = LMS_SLEEP;
2875 break;
2876 }
2877 break;
2878 case LMS_TFAULT:
2879 case LMS_DFAULT:
2880 case LMS_KFAULT:
2881 case LMS_USER_LOCK:
2882 state = LMS_SYSTEM;
2883 break;
2884 }
2885 switch (state) {
2886 case LMS_USER: mstimep = &pup->pr_utime; break;
2887 case LMS_SYSTEM: mstimep = &pup->pr_stime; break;
2888 case LMS_TRAP: mstimep = &pup->pr_ttime; break;
2889 case LMS_TFAULT: mstimep = &pup->pr_tftime; break;
2890 case LMS_DFAULT: mstimep = &pup->pr_dftime; break;
2891 case LMS_KFAULT: mstimep = &pup->pr_kftime; break;
2892 case LMS_USER_LOCK: mstimep = &pup->pr_ltime; break;
2893 case LMS_SLEEP: mstimep = &pup->pr_slptime; break;
2894 case LMS_WAIT_CPU: mstimep = &pup->pr_wtime; break;
2895 case LMS_STOPPED: mstimep = &pup->pr_stoptime; break;
2896 default: panic("prgetusage: unknown microstate");
2897 }
2898 tmp1 = curtime - ms->ms_state_start;
2899 if (tmp1 < 0) {
2900 curtime = gethrtime_unscaled();
2901 i++;
2902 continue;
2903 }
2904 scalehrtime(&tmp1);
2905 } while (tmp1 < 0 && i < MAX_ITERS_SPIN);
2906
2907 *mstimep += tmp1;
2908
2909 /* update pup timestamp */
2910 pup->pr_tstamp = curtime;
2911 scalehrtime(&pup->pr_tstamp);
2912
2913 /*
2914 * Resource usage counters.
2915 */
2916 pup->pr_minf = lwp->lwp_ru.minflt;
2917 pup->pr_majf = lwp->lwp_ru.majflt;
2918 pup->pr_nswap = lwp->lwp_ru.nswap;
2919 pup->pr_inblk = lwp->lwp_ru.inblock;
2920 pup->pr_oublk = lwp->lwp_ru.oublock;
2921 pup->pr_msnd = lwp->lwp_ru.msgsnd;
2922 pup->pr_mrcv = lwp->lwp_ru.msgrcv;
2923 pup->pr_sigs = lwp->lwp_ru.nsignals;
2924 pup->pr_vctx = lwp->lwp_ru.nvcsw;
2925 pup->pr_ictx = lwp->lwp_ru.nivcsw;
2926 pup->pr_sysc = lwp->lwp_ru.sysc;
2927 pup->pr_ioch = lwp->lwp_ru.ioch;
2928 }
2929
2930 /*
2931 * Convert ms_acct stats from unscaled high-res time to nanoseconds
2932 */
2933 void
2934 prscaleusage(prhusage_t *usg)
2935 {
2936 scalehrtime(&usg->pr_utime);
2937 scalehrtime(&usg->pr_stime);
2938 scalehrtime(&usg->pr_ttime);
2939 scalehrtime(&usg->pr_tftime);
2940 scalehrtime(&usg->pr_dftime);
2941 scalehrtime(&usg->pr_kftime);
2942 scalehrtime(&usg->pr_ltime);
2943 scalehrtime(&usg->pr_slptime);
2944 scalehrtime(&usg->pr_wtime);
2945 scalehrtime(&usg->pr_stoptime);
2946 }
2947
2948
2949 /*
2950 * Sum resource usage information.
2951 */
2952 void
2953 praddusage(kthread_t *t, prhusage_t *pup)
2954 {
2955 klwp_t *lwp = ttolwp(t);
2956 hrtime_t *mstimep;
2957 struct mstate *ms = &lwp->lwp_mstate;
2958 int state;
2959 int i;
2960 hrtime_t curtime;
2961 hrtime_t waitrq;
2962 hrtime_t tmp;
2963 prhusage_t conv;
2964
2965 curtime = gethrtime_unscaled();
2966
2967 if (ms->ms_term == 0) {
2968 tmp = curtime - ms->ms_start;
2969 scalehrtime(&tmp);
2970 pup->pr_rtime += tmp;
2971 } else {
2972 tmp = ms->ms_term - ms->ms_start;
2973 scalehrtime(&tmp);
2974 pup->pr_rtime += tmp;
2975 }
2976
2977 conv.pr_utime = ms->ms_acct[LMS_USER];
2978 conv.pr_stime = ms->ms_acct[LMS_SYSTEM];
2979 conv.pr_ttime = ms->ms_acct[LMS_TRAP];
2980 conv.pr_tftime = ms->ms_acct[LMS_TFAULT];
2981 conv.pr_dftime = ms->ms_acct[LMS_DFAULT];
2982 conv.pr_kftime = ms->ms_acct[LMS_KFAULT];
2983 conv.pr_ltime = ms->ms_acct[LMS_USER_LOCK];
2984 conv.pr_slptime = ms->ms_acct[LMS_SLEEP];
2985 conv.pr_wtime = ms->ms_acct[LMS_WAIT_CPU];
2986 conv.pr_stoptime = ms->ms_acct[LMS_STOPPED];
2987
2988 prscaleusage(&conv);
2989
2990 pup->pr_utime += conv.pr_utime;
2991 pup->pr_stime += conv.pr_stime;
2992 pup->pr_ttime += conv.pr_ttime;
2993 pup->pr_tftime += conv.pr_tftime;
2994 pup->pr_dftime += conv.pr_dftime;
2995 pup->pr_kftime += conv.pr_kftime;
2996 pup->pr_ltime += conv.pr_ltime;
2997 pup->pr_slptime += conv.pr_slptime;
2998 pup->pr_wtime += conv.pr_wtime;
2999 pup->pr_stoptime += conv.pr_stoptime;
3000
3001 /*
3002 * Adjust for time waiting in the dispatcher queue.
3003 */
3004 waitrq = t->t_waitrq; /* hopefully atomic */
3005 if (waitrq != 0) {
3006 if (waitrq > curtime) {
3007 curtime = gethrtime_unscaled();
3008 }
3009 tmp = curtime - waitrq;
3010 scalehrtime(&tmp);
3011 pup->pr_wtime += tmp;
3012 curtime = waitrq;
3013 }
3014
3015 /*
3016 * Adjust for time spent in current microstate.
3017 */
3018 if (ms->ms_state_start > curtime) {
3019 curtime = gethrtime_unscaled();
3020 }
3021
3022 i = 0;
3023 do {
3024 switch (state = t->t_mstate) {
3025 case LMS_SLEEP:
3026 /*
3027 * Update the timer for the current sleep state.
3028 */
3029 switch (state = ms->ms_prev) {
3030 case LMS_TFAULT:
3031 case LMS_DFAULT:
3032 case LMS_KFAULT:
3033 case LMS_USER_LOCK:
3034 break;
3035 default:
3036 state = LMS_SLEEP;
3037 break;
3038 }
3039 break;
3040 case LMS_TFAULT:
3041 case LMS_DFAULT:
3042 case LMS_KFAULT:
3043 case LMS_USER_LOCK:
3044 state = LMS_SYSTEM;
3045 break;
3046 }
3047 switch (state) {
3048 case LMS_USER: mstimep = &pup->pr_utime; break;
3049 case LMS_SYSTEM: mstimep = &pup->pr_stime; break;
3050 case LMS_TRAP: mstimep = &pup->pr_ttime; break;
3051 case LMS_TFAULT: mstimep = &pup->pr_tftime; break;
3052 case LMS_DFAULT: mstimep = &pup->pr_dftime; break;
3053 case LMS_KFAULT: mstimep = &pup->pr_kftime; break;
3054 case LMS_USER_LOCK: mstimep = &pup->pr_ltime; break;
3055 case LMS_SLEEP: mstimep = &pup->pr_slptime; break;
3056 case LMS_WAIT_CPU: mstimep = &pup->pr_wtime; break;
3057 case LMS_STOPPED: mstimep = &pup->pr_stoptime; break;
3058 default: panic("praddusage: unknown microstate");
3059 }
3060 tmp = curtime - ms->ms_state_start;
3061 if (tmp < 0) {
3062 curtime = gethrtime_unscaled();
3063 i++;
3064 continue;
3065 }
3066 scalehrtime(&tmp);
3067 } while (tmp < 0 && i < MAX_ITERS_SPIN);
3068
3069 *mstimep += tmp;
3070
3071 /* update pup timestamp */
3072 pup->pr_tstamp = curtime;
3073 scalehrtime(&pup->pr_tstamp);
3074
3075 /*
3076 * Resource usage counters.
3077 */
3078 pup->pr_minf += lwp->lwp_ru.minflt;
3079 pup->pr_majf += lwp->lwp_ru.majflt;
3080 pup->pr_nswap += lwp->lwp_ru.nswap;
3081 pup->pr_inblk += lwp->lwp_ru.inblock;
3082 pup->pr_oublk += lwp->lwp_ru.oublock;
3083 pup->pr_msnd += lwp->lwp_ru.msgsnd;
3084 pup->pr_mrcv += lwp->lwp_ru.msgrcv;
3085 pup->pr_sigs += lwp->lwp_ru.nsignals;
3086 pup->pr_vctx += lwp->lwp_ru.nvcsw;
3087 pup->pr_ictx += lwp->lwp_ru.nivcsw;
3088 pup->pr_sysc += lwp->lwp_ru.sysc;
3089 pup->pr_ioch += lwp->lwp_ru.ioch;
3090 }
3091
3092 /*
3093 * Convert a prhusage_t to a prusage_t.
3094 * This means convert each hrtime_t to a timestruc_t
3095 * and copy the count fields uint64_t => ulong_t.
3096 */
3097 void
3098 prcvtusage(prhusage_t *pup, prusage_t *upup)
3099 {
3100 uint64_t *ullp;
3101 ulong_t *ulp;
3102 int i;
3103
3104 upup->pr_lwpid = pup->pr_lwpid;
3105 upup->pr_count = pup->pr_count;
3106
3107 hrt2ts(pup->pr_tstamp, &upup->pr_tstamp);
3108 hrt2ts(pup->pr_create, &upup->pr_create);
3109 hrt2ts(pup->pr_term, &upup->pr_term);
3110 hrt2ts(pup->pr_rtime, &upup->pr_rtime);
3111 hrt2ts(pup->pr_utime, &upup->pr_utime);
3112 hrt2ts(pup->pr_stime, &upup->pr_stime);
3113 hrt2ts(pup->pr_ttime, &upup->pr_ttime);
3114 hrt2ts(pup->pr_tftime, &upup->pr_tftime);
3115 hrt2ts(pup->pr_dftime, &upup->pr_dftime);
3116 hrt2ts(pup->pr_kftime, &upup->pr_kftime);
3117 hrt2ts(pup->pr_ltime, &upup->pr_ltime);
3118 hrt2ts(pup->pr_slptime, &upup->pr_slptime);
3119 hrt2ts(pup->pr_wtime, &upup->pr_wtime);
3120 hrt2ts(pup->pr_stoptime, &upup->pr_stoptime);
3121 bzero(upup->filltime, sizeof (upup->filltime));
3122
3123 ullp = &pup->pr_minf;
3124 ulp = &upup->pr_minf;
3125 for (i = 0; i < 22; i++)
3126 *ulp++ = (ulong_t)*ullp++;
3127 }
3128
3129 #ifdef _SYSCALL32_IMPL
3130 void
3131 prcvtusage32(prhusage_t *pup, prusage32_t *upup)
3132 {
3133 uint64_t *ullp;
3134 uint32_t *ulp;
3135 int i;
3136
3137 upup->pr_lwpid = pup->pr_lwpid;
3138 upup->pr_count = pup->pr_count;
3139
3140 hrt2ts32(pup->pr_tstamp, &upup->pr_tstamp);
3141 hrt2ts32(pup->pr_create, &upup->pr_create);
3142 hrt2ts32(pup->pr_term, &upup->pr_term);
3143 hrt2ts32(pup->pr_rtime, &upup->pr_rtime);
3144 hrt2ts32(pup->pr_utime, &upup->pr_utime);
3145 hrt2ts32(pup->pr_stime, &upup->pr_stime);
3146 hrt2ts32(pup->pr_ttime, &upup->pr_ttime);
3147 hrt2ts32(pup->pr_tftime, &upup->pr_tftime);
3148 hrt2ts32(pup->pr_dftime, &upup->pr_dftime);
3149 hrt2ts32(pup->pr_kftime, &upup->pr_kftime);
3150 hrt2ts32(pup->pr_ltime, &upup->pr_ltime);
3151 hrt2ts32(pup->pr_slptime, &upup->pr_slptime);
3152 hrt2ts32(pup->pr_wtime, &upup->pr_wtime);
3153 hrt2ts32(pup->pr_stoptime, &upup->pr_stoptime);
3154 bzero(upup->filltime, sizeof (upup->filltime));
3155
3156 ullp = &pup->pr_minf;
3157 ulp = &upup->pr_minf;
3158 for (i = 0; i < 22; i++)
3159 *ulp++ = (uint32_t)*ullp++;
3160 }
3161 #endif /* _SYSCALL32_IMPL */
3162
3163 /*
3164 * Determine whether a set is empty.
3165 */
3166 int
3167 setisempty(uint32_t *sp, uint_t n)
3168 {
3169 while (n--)
3170 if (*sp++)
3171 return (0);
3172 return (1);
3173 }
3174
3175 /*
3176 * Utility routine for establishing a watched area in the process.
3177 * Keep the list of watched areas sorted by virtual address.
3178 */
3179 int
3180 set_watched_area(proc_t *p, struct watched_area *pwa)
3181 {
3182 caddr_t vaddr = pwa->wa_vaddr;
3183 caddr_t eaddr = pwa->wa_eaddr;
3184 ulong_t flags = pwa->wa_flags;
3185 struct watched_area *target;
3186 avl_index_t where;
3187 int error = 0;
3188
3189 /* we must not be holding p->p_lock, but the process must be locked */
3190 ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3191 ASSERT(p->p_proc_flag & P_PR_LOCK);
3192
3193 /*
3194 * If this is our first watchpoint, enable watchpoints for the process.
3195 */
3196 if (!pr_watch_active(p)) {
3197 kthread_t *t;
3198
3199 mutex_enter(&p->p_lock);
3200 if ((t = p->p_tlist) != NULL) {
3201 do {
3202 watch_enable(t);
3203 } while ((t = t->t_forw) != p->p_tlist);
3204 }
3205 mutex_exit(&p->p_lock);
3206 }
3207
3208 target = pr_find_watched_area(p, pwa, &where);
3209 if (target != NULL) {
3210 /*
3211 * We discovered an existing, overlapping watched area.
3212 * Allow it only if it is an exact match.
3213 */
3214 if (target->wa_vaddr != vaddr ||
3215 target->wa_eaddr != eaddr)
3216 error = EINVAL;
3217 else if (target->wa_flags != flags) {
3218 error = set_watched_page(p, vaddr, eaddr,
3219 flags, target->wa_flags);
3220 target->wa_flags = flags;
3221 }
3222 kmem_free(pwa, sizeof (struct watched_area));
3223 } else {
3224 avl_insert(&p->p_warea, pwa, where);
3225 error = set_watched_page(p, vaddr, eaddr, flags, 0);
3226 }
3227
3228 return (error);
3229 }
3230
3231 /*
3232 * Utility routine for clearing a watched area in the process.
3233 * Must be an exact match of the virtual address.
3234 * size and flags don't matter.
3235 */
3236 int
3237 clear_watched_area(proc_t *p, struct watched_area *pwa)
3238 {
3239 struct watched_area *found;
3240
3241 /* we must not be holding p->p_lock, but the process must be locked */
3242 ASSERT(MUTEX_NOT_HELD(&p->p_lock));
3243 ASSERT(p->p_proc_flag & P_PR_LOCK);
3244
3245
3246 if (!pr_watch_active(p)) {
3247 kmem_free(pwa, sizeof (struct watched_area));
3248 return (0);
3249 }
3250
3251 /*
3252 * Look for a matching address in the watched areas. If a match is
3253 * found, clear the old watched area and adjust the watched page(s). It
3254 * is not an error if there is no match.
3255 */
3256 if ((found = pr_find_watched_area(p, pwa, NULL)) != NULL &&
3257 found->wa_vaddr == pwa->wa_vaddr) {
3258 clear_watched_page(p, found->wa_vaddr, found->wa_eaddr,
3259 found->wa_flags);
3260 avl_remove(&p->p_warea, found);
3261 kmem_free(found, sizeof (struct watched_area));
3262 }
3263
3264 kmem_free(pwa, sizeof (struct watched_area));
3265
3266 /*
3267 * If we removed the last watched area from the process, disable
3268 * watchpoints.
3269 */
3270 if (!pr_watch_active(p)) {
3271 kthread_t *t;
3272
3273 mutex_enter(&p->p_lock);
3274 if ((t = p->p_tlist) != NULL) {
3275 do {
3276 watch_disable(t);
3277 } while ((t = t->t_forw) != p->p_tlist);
3278 }
3279 mutex_exit(&p->p_lock);
3280 }
3281
3282 return (0);
3283 }
3284
3285 /*
3286 * Frees all the watched_area structures
3287 */
3288 void
3289 pr_free_watchpoints(proc_t *p)
3290 {
3291 struct watched_area *delp;
3292 void *cookie;
3293
3294 cookie = NULL;
3295 while ((delp = avl_destroy_nodes(&p->p_warea, &cookie)) != NULL)
3296 kmem_free(delp, sizeof (struct watched_area));
3297
3298 avl_destroy(&p->p_warea);
3299 }
3300
3301 /*
3302 * This one is called by the traced process to unwatch all the
3303 * pages while deallocating the list of watched_page structs.
3304 */
3305 void
3306 pr_free_watched_pages(proc_t *p)
3307 {
3308 struct as *as = p->p_as;
3309 struct watched_page *pwp;
3310 uint_t prot;
3311 int retrycnt, err;
3312 void *cookie;
3313
3314 if (as == NULL || avl_numnodes(&as->a_wpage) == 0)
3315 return;
3316
3317 ASSERT(MUTEX_NOT_HELD(&curproc->p_lock));
3318 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3319
3320 pwp = avl_first(&as->a_wpage);
3321
3322 cookie = NULL;
3323 while ((pwp = avl_destroy_nodes(&as->a_wpage, &cookie)) != NULL) {
3324 retrycnt = 0;
3325 if ((prot = pwp->wp_oprot) != 0) {
3326 caddr_t addr = pwp->wp_vaddr;
3327 struct seg *seg;
3328 retry:
3329
3330 if ((pwp->wp_prot != prot ||
3331 (pwp->wp_flags & WP_NOWATCH)) &&
3332 (seg = as_segat(as, addr)) != NULL) {
3333 err = SEGOP_SETPROT(seg, addr, PAGESIZE, prot);
3334 if (err == IE_RETRY) {
3335 ASSERT(retrycnt == 0);
3336 retrycnt++;
3337 goto retry;
3338 }
3339 }
3340 }
3341 kmem_free(pwp, sizeof (struct watched_page));
3342 }
3343
3344 avl_destroy(&as->a_wpage);
3345 p->p_wprot = NULL;
3346
3347 AS_LOCK_EXIT(as, &as->a_lock);
3348 }
3349
3350 /*
3351 * Insert a watched area into the list of watched pages.
3352 * If oflags is zero then we are adding a new watched area.
3353 * Otherwise we are changing the flags of an existing watched area.
3354 */
3355 static int
3356 set_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr,
3357 ulong_t flags, ulong_t oflags)
3358 {
3359 struct as *as = p->p_as;
3360 avl_tree_t *pwp_tree;
3361 struct watched_page *pwp, *newpwp;
3362 struct watched_page tpw;
3363 avl_index_t where;
3364 struct seg *seg;
3365 uint_t prot;
3366 caddr_t addr;
3367
3368 /*
3369 * We need to pre-allocate a list of structures before we grab the
3370 * address space lock to avoid calling kmem_alloc(KM_SLEEP) with locks
3371 * held.
3372 */
3373 newpwp = NULL;
3374 for (addr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3375 addr < eaddr; addr += PAGESIZE) {
3376 pwp = kmem_zalloc(sizeof (struct watched_page), KM_SLEEP);
3377 pwp->wp_list = newpwp;
3378 newpwp = pwp;
3379 }
3380
3381 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3382
3383 /*
3384 * Search for an existing watched page to contain the watched area.
3385 * If none is found, grab a new one from the available list
3386 * and insert it in the active list, keeping the list sorted
3387 * by user-level virtual address.
3388 */
3389 if (p->p_flag & SVFWAIT)
3390 pwp_tree = &p->p_wpage;
3391 else
3392 pwp_tree = &as->a_wpage;
3393
3394 again:
3395 if (avl_numnodes(pwp_tree) > prnwatch) {
3396 AS_LOCK_EXIT(as, &as->a_lock);
3397 while (newpwp != NULL) {
3398 pwp = newpwp->wp_list;
3399 kmem_free(newpwp, sizeof (struct watched_page));
3400 newpwp = pwp;
3401 }
3402 return (E2BIG);
3403 }
3404
3405 tpw.wp_vaddr = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3406 if ((pwp = avl_find(pwp_tree, &tpw, &where)) == NULL) {
3407 pwp = newpwp;
3408 newpwp = newpwp->wp_list;
3409 pwp->wp_list = NULL;
3410 pwp->wp_vaddr = (caddr_t)((uintptr_t)vaddr &
3411 (uintptr_t)PAGEMASK);
3412 avl_insert(pwp_tree, pwp, where);
3413 }
3414
3415 ASSERT(vaddr >= pwp->wp_vaddr && vaddr < pwp->wp_vaddr + PAGESIZE);
3416
3417 if (oflags & WA_READ)
3418 pwp->wp_read--;
3419 if (oflags & WA_WRITE)
3420 pwp->wp_write--;
3421 if (oflags & WA_EXEC)
3422 pwp->wp_exec--;
3423
3424 ASSERT(pwp->wp_read >= 0);
3425 ASSERT(pwp->wp_write >= 0);
3426 ASSERT(pwp->wp_exec >= 0);
3427
3428 if (flags & WA_READ)
3429 pwp->wp_read++;
3430 if (flags & WA_WRITE)
3431 pwp->wp_write++;
3432 if (flags & WA_EXEC)
3433 pwp->wp_exec++;
3434
3435 if (!(p->p_flag & SVFWAIT)) {
3436 vaddr = pwp->wp_vaddr;
3437 if (pwp->wp_oprot == 0 &&
3438 (seg = as_segat(as, vaddr)) != NULL) {
3439 SEGOP_GETPROT(seg, vaddr, 0, &prot);
3440 pwp->wp_oprot = (uchar_t)prot;
3441 pwp->wp_prot = (uchar_t)prot;
3442 }
3443 if (pwp->wp_oprot != 0) {
3444 prot = pwp->wp_oprot;
3445 if (pwp->wp_read)
3446 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3447 if (pwp->wp_write)
3448 prot &= ~PROT_WRITE;
3449 if (pwp->wp_exec)
3450 prot &= ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3451 if (!(pwp->wp_flags & WP_NOWATCH) &&
3452 pwp->wp_prot != prot &&
3453 (pwp->wp_flags & WP_SETPROT) == 0) {
3454 pwp->wp_flags |= WP_SETPROT;
3455 pwp->wp_list = p->p_wprot;
3456 p->p_wprot = pwp;
3457 }
3458 pwp->wp_prot = (uchar_t)prot;
3459 }
3460 }
3461
3462 /*
3463 * If the watched area extends into the next page then do
3464 * it over again with the virtual address of the next page.
3465 */
3466 if ((vaddr = pwp->wp_vaddr + PAGESIZE) < eaddr)
3467 goto again;
3468
3469 AS_LOCK_EXIT(as, &as->a_lock);
3470
3471 /*
3472 * Free any pages we may have over-allocated
3473 */
3474 while (newpwp != NULL) {
3475 pwp = newpwp->wp_list;
3476 kmem_free(newpwp, sizeof (struct watched_page));
3477 newpwp = pwp;
3478 }
3479
3480 return (0);
3481 }
3482
3483 /*
3484 * Remove a watched area from the list of watched pages.
3485 * A watched area may extend over more than one page.
3486 */
3487 static void
3488 clear_watched_page(proc_t *p, caddr_t vaddr, caddr_t eaddr, ulong_t flags)
3489 {
3490 struct as *as = p->p_as;
3491 struct watched_page *pwp;
3492 struct watched_page tpw;
3493 avl_tree_t *tree;
3494 avl_index_t where;
3495
3496 AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
3497
3498 if (p->p_flag & SVFWAIT)
3499 tree = &p->p_wpage;
3500 else
3501 tree = &as->a_wpage;
3502
3503 tpw.wp_vaddr = vaddr =
3504 (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK);
3505 pwp = avl_find(tree, &tpw, &where);
3506 if (pwp == NULL)
3507 pwp = avl_nearest(tree, where, AVL_AFTER);
3508
3509 while (pwp != NULL && pwp->wp_vaddr < eaddr) {
3510 ASSERT(vaddr <= pwp->wp_vaddr);
3511
3512 if (flags & WA_READ)
3513 pwp->wp_read--;
3514 if (flags & WA_WRITE)
3515 pwp->wp_write--;
3516 if (flags & WA_EXEC)
3517 pwp->wp_exec--;
3518
3519 if (pwp->wp_read + pwp->wp_write + pwp->wp_exec != 0) {
3520 /*
3521 * Reset the hat layer's protections on this page.
3522 */
3523 if (pwp->wp_oprot != 0) {
3524 uint_t prot = pwp->wp_oprot;
3525
3526 if (pwp->wp_read)
3527 prot &=
3528 ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3529 if (pwp->wp_write)
3530 prot &= ~PROT_WRITE;
3531 if (pwp->wp_exec)
3532 prot &=
3533 ~(PROT_READ|PROT_WRITE|PROT_EXEC);
3534 if (!(pwp->wp_flags & WP_NOWATCH) &&
3535 pwp->wp_prot != prot &&
3536 (pwp->wp_flags & WP_SETPROT) == 0) {
3537 pwp->wp_flags |= WP_SETPROT;
3538 pwp->wp_list = p->p_wprot;
3539 p->p_wprot = pwp;
3540 }
3541 pwp->wp_prot = (uchar_t)prot;
3542 }
3543 } else {
3544 /*
3545 * No watched areas remain in this page.
3546 * Reset everything to normal.
3547 */
3548 if (pwp->wp_oprot != 0) {
3549 pwp->wp_prot = pwp->wp_oprot;
3550 if ((pwp->wp_flags & WP_SETPROT) == 0) {
3551 pwp->wp_flags |= WP_SETPROT;
3552 pwp->wp_list = p->p_wprot;
3553 p->p_wprot = pwp;
3554 }
3555 }
3556 }
3557
3558 pwp = AVL_NEXT(tree, pwp);
3559 }
3560
3561 AS_LOCK_EXIT(as, &as->a_lock);
3562 }
3563
3564 /*
3565 * Return the original protections for the specified page.
3566 */
3567 static void
3568 getwatchprot(struct as *as, caddr_t addr, uint_t *prot)
3569 {
3570 struct watched_page *pwp;
3571 struct watched_page tpw;
3572
3573 ASSERT(AS_LOCK_HELD(as, &as->a_lock));
3574
3575 tpw.wp_vaddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK);
3576 if ((pwp = avl_find(&as->a_wpage, &tpw, NULL)) != NULL)
3577 *prot = pwp->wp_oprot;
3578 }
3579
3580 static prpagev_t *
3581 pr_pagev_create(struct seg *seg, int check_noreserve)
3582 {
3583 prpagev_t *pagev = kmem_alloc(sizeof (prpagev_t), KM_SLEEP);
3584 size_t total_pages = seg_pages(seg);
3585
3586 /*
3587 * Limit the size of our vectors to pagev_lim pages at a time. We need
3588 * 4 or 5 bytes of storage per page, so this means we limit ourself
3589 * to about a megabyte of kernel heap by default.
3590 */
3591 pagev->pg_npages = MIN(total_pages, pagev_lim);
3592 pagev->pg_pnbase = 0;
3593
3594 pagev->pg_protv =
3595 kmem_alloc(pagev->pg_npages * sizeof (uint_t), KM_SLEEP);
3596
3597 if (check_noreserve)
3598 pagev->pg_incore =
3599 kmem_alloc(pagev->pg_npages * sizeof (char), KM_SLEEP);
3600 else
3601 pagev->pg_incore = NULL;
3602
3603 return (pagev);
3604 }
3605
3606 static void
3607 pr_pagev_destroy(prpagev_t *pagev)
3608 {
3609 if (pagev->pg_incore != NULL)
3610 kmem_free(pagev->pg_incore, pagev->pg_npages * sizeof (char));
3611
3612 kmem_free(pagev->pg_protv, pagev->pg_npages * sizeof (uint_t));
3613 kmem_free(pagev, sizeof (prpagev_t));
3614 }
3615
3616 static caddr_t
3617 pr_pagev_fill(prpagev_t *pagev, struct seg *seg, caddr_t addr, caddr_t eaddr)
3618 {
3619 ulong_t lastpg = seg_page(seg, eaddr - 1);
3620 ulong_t pn, pnlim;
3621 caddr_t saddr;
3622 size_t len;
3623
3624 ASSERT(addr >= seg->s_base && addr <= eaddr);
3625
3626 if (addr == eaddr)
3627 return (eaddr);
3628
3629 refill:
3630 ASSERT(addr < eaddr);
3631 pagev->pg_pnbase = seg_page(seg, addr);
3632 pnlim = pagev->pg_pnbase + pagev->pg_npages;
3633 saddr = addr;
3634
3635 if (lastpg < pnlim)
3636 len = (size_t)(eaddr - addr);
3637 else
3638 len = pagev->pg_npages * PAGESIZE;
3639
3640 if (pagev->pg_incore != NULL) {
3641 /*
3642 * INCORE cleverly has different semantics than GETPROT:
3643 * it returns info on pages up to but NOT including addr + len.
3644 */
3645 SEGOP_INCORE(seg, addr, len, pagev->pg_incore);
3646 pn = pagev->pg_pnbase;
3647
3648 do {
3649 /*
3650 * Guilty knowledge here: We know that segvn_incore
3651 * returns more than just the low-order bit that
3652 * indicates the page is actually in memory. If any
3653 * bits are set, then the page has backing store.
3654 */
3655 if (pagev->pg_incore[pn++ - pagev->pg_pnbase])
3656 goto out;
3657
3658 } while ((addr += PAGESIZE) < eaddr && pn < pnlim);
3659
3660 /*
3661 * If we examined all the pages in the vector but we're not
3662 * at the end of the segment, take another lap.
3663 */
3664 if (addr < eaddr)
3665 goto refill;
3666 }
3667
3668 /*
3669 * Need to take len - 1 because addr + len is the address of the
3670 * first byte of the page just past the end of what we want.
3671 */
3672 out:
3673 SEGOP_GETPROT(seg, saddr, len - 1, pagev->pg_protv);
3674 return (addr);
3675 }
3676
3677 static caddr_t
3678 pr_pagev_nextprot(prpagev_t *pagev, struct seg *seg,
3679 caddr_t *saddrp, caddr_t eaddr, uint_t *protp)
3680 {
3681 /*
3682 * Our starting address is either the specified address, or the base
3683 * address from the start of the pagev. If the latter is greater,
3684 * this means a previous call to pr_pagev_fill has already scanned
3685 * further than the end of the previous mapping.
3686 */
3687 caddr_t base = seg->s_base + pagev->pg_pnbase * PAGESIZE;
3688 caddr_t addr = MAX(*saddrp, base);
3689 ulong_t pn = seg_page(seg, addr);
3690 uint_t prot, nprot;
3691
3692 /*
3693 * If we're dealing with noreserve pages, then advance addr to
3694 * the address of the next page which has backing store.
3695 */
3696 if (pagev->pg_incore != NULL) {
3697 while (pagev->pg_incore[pn - pagev->pg_pnbase] == 0) {
3698 if ((addr += PAGESIZE) == eaddr) {
3699 *saddrp = addr;
3700 prot = 0;
3701 goto out;
3702 }
3703 if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
3704 addr = pr_pagev_fill(pagev, seg, addr, eaddr);
3705 if (addr == eaddr) {
3706 *saddrp = addr;
3707 prot = 0;
3708 goto out;
3709 }
3710 pn = seg_page(seg, addr);
3711 }
3712 }
3713 }
3714
3715 /*
3716 * Get the protections on the page corresponding to addr.
3717 */
3718 pn = seg_page(seg, addr);
3719 ASSERT(pn >= pagev->pg_pnbase);
3720 ASSERT(pn < (pagev->pg_pnbase + pagev->pg_npages));
3721
3722 prot = pagev->pg_protv[pn - pagev->pg_pnbase];
3723 getwatchprot(seg->s_as, addr, &prot);
3724 *saddrp = addr;
3725
3726 /*
3727 * Now loop until we find a backed page with different protections
3728 * or we reach the end of this segment.
3729 */
3730 while ((addr += PAGESIZE) < eaddr) {
3731 /*
3732 * If pn has advanced to the page number following what we
3733 * have information on, refill the page vector and reset
3734 * addr and pn. If pr_pagev_fill does not return the
3735 * address of the next page, we have a discontiguity and
3736 * thus have reached the end of the current mapping.
3737 */
3738 if (++pn == pagev->pg_pnbase + pagev->pg_npages) {
3739 caddr_t naddr = pr_pagev_fill(pagev, seg, addr, eaddr);
3740 if (naddr != addr)
3741 goto out;
3742 pn = seg_page(seg, addr);
3743 }
3744
3745 /*
3746 * The previous page's protections are in prot, and it has
3747 * backing. If this page is MAP_NORESERVE and has no backing,
3748 * then end this mapping and return the previous protections.
3749 */
3750 if (pagev->pg_incore != NULL &&
3751 pagev->pg_incore[pn - pagev->pg_pnbase] == 0)
3752 break;
3753
3754 /*
3755 * Otherwise end the mapping if this page's protections (nprot)
3756 * are different than those in the previous page (prot).
3757 */
3758 nprot = pagev->pg_protv[pn - pagev->pg_pnbase];
3759 getwatchprot(seg->s_as, addr, &nprot);
3760
3761 if (nprot != prot)
3762 break;
3763 }
3764
3765 out:
3766 *protp = prot;
3767 return (addr);
3768 }
3769
3770 size_t
3771 pr_getsegsize(struct seg *seg, int reserved)
3772 {
3773 size_t size = seg->s_size;
3774
3775 /*
3776 * If we're interested in the reserved space, return the size of the
3777 * segment itself. Everything else in this function is a special case
3778 * to determine the actual underlying size of various segment types.
3779 */
3780 if (reserved)
3781 return (size);
3782
3783 /*
3784 * If this is a segvn mapping of a regular file, return the smaller
3785 * of the segment size and the remaining size of the file beyond
3786 * the file offset corresponding to seg->s_base.
3787 */
3788 if (seg->s_ops == &segvn_ops) {
3789 vattr_t vattr;
3790 vnode_t *vp;
3791
3792 vattr.va_mask = AT_SIZE;
3793
3794 if (SEGOP_GETVP(seg, seg->s_base, &vp) == 0 &&
3795 vp != NULL && vp->v_type == VREG &&
3796 VOP_GETATTR(vp, &vattr, 0, CRED(), NULL) == 0) {
3797
3798 u_offset_t fsize = vattr.va_size;
3799 u_offset_t offset = SEGOP_GETOFFSET(seg, seg->s_base);
3800
3801 if (fsize < offset)
3802 fsize = 0;
3803 else
3804 fsize -= offset;
3805
3806 fsize = roundup(fsize, (u_offset_t)PAGESIZE);
3807
3808 if (fsize < (u_offset_t)size)
3809 size = (size_t)fsize;
3810 }
3811
3812 return (size);
3813 }
3814
3815 /*
3816 * If this is an ISM shared segment, don't include pages that are
3817 * beyond the real size of the spt segment that backs it.
3818 */
3819 if (seg->s_ops == &segspt_shmops)
3820 return (MIN(spt_realsize(seg), size));
3821
3822 /*
3823 * If this is segment is a mapping from /dev/null, then this is a
3824 * reservation of virtual address space and has no actual size.
3825 * Such segments are backed by segdev and have type set to neither
3826 * MAP_SHARED nor MAP_PRIVATE.
3827 */
3828 if (seg->s_ops == &segdev_ops &&
3829 ((SEGOP_GETTYPE(seg, seg->s_base) &
3830 (MAP_SHARED | MAP_PRIVATE)) == 0))
3831 return (0);
3832
3833 /*
3834 * If this segment doesn't match one of the special types we handle,
3835 * just return the size of the segment itself.
3836 */
3837 return (size);
3838 }
3839
3840 uint_t
3841 pr_getprot(struct seg *seg, int reserved, void **tmp,
3842 caddr_t *saddrp, caddr_t *naddrp, caddr_t eaddr)
3843 {
3844 struct as *as = seg->s_as;
3845
3846 caddr_t saddr = *saddrp;
3847 caddr_t naddr;
3848
3849 int check_noreserve;
3850 uint_t prot;
3851
3852 union {
3853 struct segvn_data *svd;
3854 struct segdev_data *sdp;
3855 void *data;
3856 } s;
3857
3858 s.data = seg->s_data;
3859
3860 ASSERT(AS_WRITE_HELD(as, &as->a_lock));
3861 ASSERT(saddr >= seg->s_base && saddr < eaddr);
3862 ASSERT(eaddr <= seg->s_base + seg->s_size);
3863
3864 /*
3865 * Don't include MAP_NORESERVE pages in the address range
3866 * unless their mappings have actually materialized.
3867 * We cheat by knowing that segvn is the only segment
3868 * driver that supports MAP_NORESERVE.
3869 */
3870 check_noreserve =
3871 (!reserved && seg->s_ops == &segvn_ops && s.svd != NULL &&
3872 (s.svd->vp == NULL || s.svd->vp->v_type != VREG) &&
3873 (s.svd->flags & MAP_NORESERVE));
3874
3875 /*
3876 * Examine every page only as a last resort. We use guilty knowledge
3877 * of segvn and segdev to avoid this: if there are no per-page
3878 * protections present in the segment and we don't care about
3879 * MAP_NORESERVE, then s_data->prot is the prot for the whole segment.
3880 */
3881 if (!check_noreserve && saddr == seg->s_base &&
3882 seg->s_ops == &segvn_ops && s.svd != NULL && s.svd->pageprot == 0) {
3883 prot = s.svd->prot;
3884 getwatchprot(as, saddr, &prot);
3885 naddr = eaddr;
3886
3887 } else if (saddr == seg->s_base && seg->s_ops == &segdev_ops &&
3888 s.sdp != NULL && s.sdp->pageprot == 0) {
3889 prot = s.sdp->prot;
3890 getwatchprot(as, saddr, &prot);
3891 naddr = eaddr;
3892
3893 } else {
3894 prpagev_t *pagev;
3895
3896 /*
3897 * If addr is sitting at the start of the segment, then
3898 * create a page vector to store protection and incore
3899 * information for pages in the segment, and fill it.
3900 * Otherwise, we expect *tmp to address the prpagev_t
3901 * allocated by a previous call to this function.
3902 */
3903 if (saddr == seg->s_base) {
3904 pagev = pr_pagev_create(seg, check_noreserve);
3905 saddr = pr_pagev_fill(pagev, seg, saddr, eaddr);
3906
3907 ASSERT(*tmp == NULL);
3908 *tmp = pagev;
3909
3910 ASSERT(saddr <= eaddr);
3911 *saddrp = saddr;
3912
3913 if (saddr == eaddr) {
3914 naddr = saddr;
3915 prot = 0;
3916 goto out;
3917 }
3918
3919 } else {
3920 ASSERT(*tmp != NULL);
3921 pagev = (prpagev_t *)*tmp;
3922 }
3923
3924 naddr = pr_pagev_nextprot(pagev, seg, saddrp, eaddr, &prot);
3925 ASSERT(naddr <= eaddr);
3926 }
3927
3928 out:
3929 if (naddr == eaddr)
3930 pr_getprot_done(tmp);
3931 *naddrp = naddr;
3932 return (prot);
3933 }
3934
3935 void
3936 pr_getprot_done(void **tmp)
3937 {
3938 if (*tmp != NULL) {
3939 pr_pagev_destroy((prpagev_t *)*tmp);
3940 *tmp = NULL;
3941 }
3942 }
3943
3944 /*
3945 * Return true iff the vnode is a /proc file from the object directory.
3946 */
3947 int
3948 pr_isobject(vnode_t *vp)
3949 {
3950 return (vn_matchops(vp, prvnodeops) && VTOP(vp)->pr_type == PR_OBJECT);
3951 }
3952
3953 /*
3954 * Return true iff the vnode is a /proc file opened by the process itself.
3955 */
3956 int
3957 pr_isself(vnode_t *vp)
3958 {
3959 /*
3960 * XXX: To retain binary compatibility with the old
3961 * ioctl()-based version of /proc, we exempt self-opens
3962 * of /proc/<pid> from being marked close-on-exec.
3963 */
3964 return (vn_matchops(vp, prvnodeops) &&
3965 (VTOP(vp)->pr_flags & PR_ISSELF) &&
3966 VTOP(vp)->pr_type != PR_PIDDIR);
3967 }
3968
3969 static ssize_t
3970 pr_getpagesize(struct seg *seg, caddr_t saddr, caddr_t *naddrp, caddr_t eaddr)
3971 {
3972 ssize_t pagesize, hatsize;
3973
3974 ASSERT(AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
3975 ASSERT(IS_P2ALIGNED(saddr, PAGESIZE));
3976 ASSERT(IS_P2ALIGNED(eaddr, PAGESIZE));
3977 ASSERT(saddr < eaddr);
3978
3979 pagesize = hatsize = hat_getpagesize(seg->s_as->a_hat, saddr);
3980 ASSERT(pagesize == -1 || IS_P2ALIGNED(pagesize, pagesize));
3981 ASSERT(pagesize != 0);
3982
3983 if (pagesize == -1)
3984 pagesize = PAGESIZE;
3985
3986 saddr += P2NPHASE((uintptr_t)saddr, pagesize);
3987
3988 while (saddr < eaddr) {
3989 if (hatsize != hat_getpagesize(seg->s_as->a_hat, saddr))
3990 break;
3991 ASSERT(IS_P2ALIGNED(saddr, pagesize));
3992 saddr += pagesize;
3993 }
3994
3995 *naddrp = ((saddr < eaddr) ? saddr : eaddr);
3996 return (hatsize);
3997 }
3998
3999 /*
4000 * Return an array of structures with extended memory map information.
4001 * We allocate here; the caller must deallocate.
4002 */
4003 int
4004 prgetxmap(proc_t *p, list_t *iolhead)
4005 {
4006 struct as *as = p->p_as;
4007 prxmap_t *mp;
4008 struct seg *seg;
4009 struct seg *brkseg, *stkseg;
4010 struct vnode *vp;
4011 struct vattr vattr;
4012 uint_t prot;
4013
4014 ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
4015
4016 /*
4017 * Request an initial buffer size that doesn't waste memory
4018 * if the address space has only a small number of segments.
4019 */
4020 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4021
4022 if ((seg = AS_SEGFIRST(as)) == NULL)
4023 return (0);
4024
4025 brkseg = break_seg(p);
4026 stkseg = as_segat(as, prgetstackbase(p));
4027
4028 do {
4029 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4030 caddr_t saddr, naddr, baddr;
4031 void *tmp = NULL;
4032 ssize_t psz;
4033 char *parr;
4034 uint64_t npages;
4035 uint64_t pagenum;
4036
4037 /*
4038 * Segment loop part one: iterate from the base of the segment
4039 * to its end, pausing at each address boundary (baddr) between
4040 * ranges that have different virtual memory protections.
4041 */
4042 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4043 prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4044 ASSERT(baddr >= saddr && baddr <= eaddr);
4045
4046 /*
4047 * Segment loop part two: iterate from the current
4048 * position to the end of the protection boundary,
4049 * pausing at each address boundary (naddr) between
4050 * ranges that have different underlying page sizes.
4051 */
4052 for (; saddr < baddr; saddr = naddr) {
4053 psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4054 ASSERT(naddr >= saddr && naddr <= baddr);
4055
4056 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4057
4058 mp->pr_vaddr = (uintptr_t)saddr;
4059 mp->pr_size = naddr - saddr;
4060 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4061 mp->pr_mflags = 0;
4062 if (prot & PROT_READ)
4063 mp->pr_mflags |= MA_READ;
4064 if (prot & PROT_WRITE)
4065 mp->pr_mflags |= MA_WRITE;
4066 if (prot & PROT_EXEC)
4067 mp->pr_mflags |= MA_EXEC;
4068 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4069 mp->pr_mflags |= MA_SHARED;
4070 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4071 mp->pr_mflags |= MA_NORESERVE;
4072 if (seg->s_ops == &segspt_shmops ||
4073 (seg->s_ops == &segvn_ops &&
4074 (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4075 vp == NULL)))
4076 mp->pr_mflags |= MA_ANON;
4077 if (seg == brkseg)
4078 mp->pr_mflags |= MA_BREAK;
4079 else if (seg == stkseg)
4080 mp->pr_mflags |= MA_STACK;
4081 if (seg->s_ops == &segspt_shmops)
4082 mp->pr_mflags |= MA_ISM | MA_SHM;
4083
4084 mp->pr_pagesize = PAGESIZE;
4085 if (psz == -1) {
4086 mp->pr_hatpagesize = 0;
4087 } else {
4088 mp->pr_hatpagesize = psz;
4089 }
4090
4091 /*
4092 * Manufacture a filename for the "object" dir.
4093 */
4094 mp->pr_dev = PRNODEV;
4095 vattr.va_mask = AT_FSID|AT_NODEID;
4096 if (seg->s_ops == &segvn_ops &&
4097 SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4098 vp != NULL && vp->v_type == VREG &&
4099 VOP_GETATTR(vp, &vattr, 0, CRED(),
4100 NULL) == 0) {
4101 mp->pr_dev = vattr.va_fsid;
4102 mp->pr_ino = vattr.va_nodeid;
4103 if (vp == p->p_exec)
4104 (void) strcpy(mp->pr_mapname,
4105 "a.out");
4106 else
4107 pr_object_name(mp->pr_mapname,
4108 vp, &vattr);
4109 }
4110
4111 /*
4112 * Get the SysV shared memory id, if any.
4113 */
4114 if ((mp->pr_mflags & MA_SHARED) &&
4115 p->p_segacct && (mp->pr_shmid = shmgetid(p,
4116 seg->s_base)) != SHMID_NONE) {
4117 if (mp->pr_shmid == SHMID_FREE)
4118 mp->pr_shmid = -1;
4119
4120 mp->pr_mflags |= MA_SHM;
4121 } else {
4122 mp->pr_shmid = -1;
4123 }
4124
4125 npages = ((uintptr_t)(naddr - saddr)) >>
4126 PAGESHIFT;
4127 parr = kmem_zalloc(npages, KM_SLEEP);
4128
4129 SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4130
4131 for (pagenum = 0; pagenum < npages; pagenum++) {
4132 if (parr[pagenum] & SEG_PAGE_INCORE)
4133 mp->pr_rss++;
4134 if (parr[pagenum] & SEG_PAGE_ANON)
4135 mp->pr_anon++;
4136 if (parr[pagenum] & SEG_PAGE_LOCKED)
4137 mp->pr_locked++;
4138 }
4139 kmem_free(parr, npages);
4140 }
4141 }
4142 ASSERT(tmp == NULL);
4143 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4144
4145 return (0);
4146 }
4147
4148 /*
4149 * Return the process's credentials. We don't need a 32-bit equivalent of
4150 * this function because prcred_t and prcred32_t are actually the same.
4151 */
4152 void
4153 prgetcred(proc_t *p, prcred_t *pcrp)
4154 {
4155 mutex_enter(&p->p_crlock);
4156 cred2prcred(p->p_cred, pcrp);
4157 mutex_exit(&p->p_crlock);
4158 }
4159
4160 /*
4161 * Compute actual size of the prpriv_t structure.
4162 */
4163
4164 size_t
4165 prgetprivsize(void)
4166 {
4167 return (priv_prgetprivsize(NULL));
4168 }
4169
4170 /*
4171 * Return the process's privileges. We don't need a 32-bit equivalent of
4172 * this function because prpriv_t and prpriv32_t are actually the same.
4173 */
4174 void
4175 prgetpriv(proc_t *p, prpriv_t *pprp)
4176 {
4177 mutex_enter(&p->p_crlock);
4178 cred2prpriv(p->p_cred, pprp);
4179 mutex_exit(&p->p_crlock);
4180 }
4181
4182 #ifdef _SYSCALL32_IMPL
4183 /*
4184 * Return an array of structures with HAT memory map information.
4185 * We allocate here; the caller must deallocate.
4186 */
4187 int
4188 prgetxmap32(proc_t *p, list_t *iolhead)
4189 {
4190 struct as *as = p->p_as;
4191 prxmap32_t *mp;
4192 struct seg *seg;
4193 struct seg *brkseg, *stkseg;
4194 struct vnode *vp;
4195 struct vattr vattr;
4196 uint_t prot;
4197
4198 ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
4199
4200 /*
4201 * Request an initial buffer size that doesn't waste memory
4202 * if the address space has only a small number of segments.
4203 */
4204 pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
4205
4206 if ((seg = AS_SEGFIRST(as)) == NULL)
4207 return (0);
4208
4209 brkseg = break_seg(p);
4210 stkseg = as_segat(as, prgetstackbase(p));
4211
4212 do {
4213 caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
4214 caddr_t saddr, naddr, baddr;
4215 void *tmp = NULL;
4216 ssize_t psz;
4217 char *parr;
4218 uint64_t npages;
4219 uint64_t pagenum;
4220
4221 /*
4222 * Segment loop part one: iterate from the base of the segment
4223 * to its end, pausing at each address boundary (baddr) between
4224 * ranges that have different virtual memory protections.
4225 */
4226 for (saddr = seg->s_base; saddr < eaddr; saddr = baddr) {
4227 prot = pr_getprot(seg, 0, &tmp, &saddr, &baddr, eaddr);
4228 ASSERT(baddr >= saddr && baddr <= eaddr);
4229
4230 /*
4231 * Segment loop part two: iterate from the current
4232 * position to the end of the protection boundary,
4233 * pausing at each address boundary (naddr) between
4234 * ranges that have different underlying page sizes.
4235 */
4236 for (; saddr < baddr; saddr = naddr) {
4237 psz = pr_getpagesize(seg, saddr, &naddr, baddr);
4238 ASSERT(naddr >= saddr && naddr <= baddr);
4239
4240 mp = pr_iol_newbuf(iolhead, sizeof (*mp));
4241
4242 mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
4243 mp->pr_size = (size32_t)(naddr - saddr);
4244 mp->pr_offset = SEGOP_GETOFFSET(seg, saddr);
4245 mp->pr_mflags = 0;
4246 if (prot & PROT_READ)
4247 mp->pr_mflags |= MA_READ;
4248 if (prot & PROT_WRITE)
4249 mp->pr_mflags |= MA_WRITE;
4250 if (prot & PROT_EXEC)
4251 mp->pr_mflags |= MA_EXEC;
4252 if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
4253 mp->pr_mflags |= MA_SHARED;
4254 if (SEGOP_GETTYPE(seg, saddr) & MAP_NORESERVE)
4255 mp->pr_mflags |= MA_NORESERVE;
4256 if (seg->s_ops == &segspt_shmops ||
4257 (seg->s_ops == &segvn_ops &&
4258 (SEGOP_GETVP(seg, saddr, &vp) != 0 ||
4259 vp == NULL)))
4260 mp->pr_mflags |= MA_ANON;
4261 if (seg == brkseg)
4262 mp->pr_mflags |= MA_BREAK;
4263 else if (seg == stkseg)
4264 mp->pr_mflags |= MA_STACK;
4265 if (seg->s_ops == &segspt_shmops)
4266 mp->pr_mflags |= MA_ISM | MA_SHM;
4267
4268 mp->pr_pagesize = PAGESIZE;
4269 if (psz == -1) {
4270 mp->pr_hatpagesize = 0;
4271 } else {
4272 mp->pr_hatpagesize = psz;
4273 }
4274
4275 /*
4276 * Manufacture a filename for the "object" dir.
4277 */
4278 mp->pr_dev = PRNODEV32;
4279 vattr.va_mask = AT_FSID|AT_NODEID;
4280 if (seg->s_ops == &segvn_ops &&
4281 SEGOP_GETVP(seg, saddr, &vp) == 0 &&
4282 vp != NULL && vp->v_type == VREG &&
4283 VOP_GETATTR(vp, &vattr, 0, CRED(),
4284 NULL) == 0) {
4285 (void) cmpldev(&mp->pr_dev,
4286 vattr.va_fsid);
4287 mp->pr_ino = vattr.va_nodeid;
4288 if (vp == p->p_exec)
4289 (void) strcpy(mp->pr_mapname,
4290 "a.out");
4291 else
4292 pr_object_name(mp->pr_mapname,
4293 vp, &vattr);
4294 }
4295
4296 /*
4297 * Get the SysV shared memory id, if any.
4298 */
4299 if ((mp->pr_mflags & MA_SHARED) &&
4300 p->p_segacct && (mp->pr_shmid = shmgetid(p,
4301 seg->s_base)) != SHMID_NONE) {
4302 if (mp->pr_shmid == SHMID_FREE)
4303 mp->pr_shmid = -1;
4304
4305 mp->pr_mflags |= MA_SHM;
4306 } else {
4307 mp->pr_shmid = -1;
4308 }
4309
4310 npages = ((uintptr_t)(naddr - saddr)) >>
4311 PAGESHIFT;
4312 parr = kmem_zalloc(npages, KM_SLEEP);
4313
4314 SEGOP_INCORE(seg, saddr, naddr - saddr, parr);
4315
4316 for (pagenum = 0; pagenum < npages; pagenum++) {
4317 if (parr[pagenum] & SEG_PAGE_INCORE)
4318 mp->pr_rss++;
4319 if (parr[pagenum] & SEG_PAGE_ANON)
4320 mp->pr_anon++;
4321 if (parr[pagenum] & SEG_PAGE_LOCKED)
4322 mp->pr_locked++;
4323 }
4324 kmem_free(parr, npages);
4325 }
4326 }
4327 ASSERT(tmp == NULL);
4328 } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
4329
4330 return (0);
4331 }
4332 #endif /* _SYSCALL32_IMPL */