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