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