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.
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.
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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2017 Joyent, Inc.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All rights reserved. */
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/vmparam.h>
35 #include <sys/cmn_err.h>
37 #include <sys/debug.h>
38 #include <sys/errno.h>
40 #include <sys/inline.h>
43 #include <sys/brand.h>
44 #include <sys/sysmacros.h>
45 #include <sys/systm.h>
47 #include <sys/vnode.h>
48 #include <sys/cpuvar.h>
49 #include <sys/session.h>
50 #include <sys/signal.h>
54 #include <sys/class.h>
57 #include <sys/fault.h>
58 #include <sys/syscall.h>
59 #include <sys/schedctl.h>
61 #include <sys/old_procfs.h>
64 #include <sys/msacct.h>
69 #include <vm/seg_vn.h>
70 #include <sys/contract_impl.h>
71 #include <sys/ctfs_impl.h>
74 #if defined(__i386) || defined(__i386_COMPAT)
75 #include <sys/sysi86.h>
78 #include <sys/proc/prdata.h>
80 static int isprwrioctl(int);
81 static ulong_t
prmaprunflags(long);
82 static long prmapsetflags(long);
83 static void prsetrun(kthread_t
*, prrun_t
*);
84 static int propenm(prnode_t
*, caddr_t
, caddr_t
, int *, cred_t
*);
85 extern void oprgetstatus(kthread_t
*, prstatus_t
*, zone_t
*);
86 extern void oprgetpsinfo(proc_t
*, prpsinfo_t
*, kthread_t
*);
87 static int oprgetmap(proc_t
*, list_t
*);
90 prctioctl(prnode_t
*pnp
, int cmd
, intptr_t arg
, int flag
, cred_t
*cr
)
94 ct_param_t
*param
= &kparam
.param
;
97 if (cmd
!= CT_TSET
&& cmd
!= CT_TGET
)
100 error
= ctparam_copyin((void *)arg
, &kparam
, flag
, cmd
);
104 if ((error
= prlock(pnp
, ZNO
)) != 0) {
105 kmem_free(kparam
.ctpm_kbuf
, param
->ctpm_size
);
109 tmpl
= pnp
->pr_common
->prc_thread
->t_lwp
->lwp_ct_active
[pnp
->pr_cttype
];
112 kmem_free(kparam
.ctpm_kbuf
, param
->ctpm_size
);
117 error
= ctmpl_set(tmpl
, &kparam
, cr
);
119 error
= ctmpl_get(tmpl
, &kparam
);
123 if (cmd
== CT_TGET
&& error
== 0) {
124 error
= ctparam_copyout(&kparam
, (void *)arg
, flag
);
126 kmem_free(kparam
.ctpm_kbuf
, param
->ctpm_size
);
134 * Control operations (lots).
136 /* ARGSUSED */ /* BEGIN CSTYLED */
137 #ifdef _SYSCALL32_IMPL
146 caller_context_t
*ct
)
156 caller_context_t
*ct
)
157 #endif /* _SYSCALL32_IMPL */ /* END CSTYLED */
159 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
160 caddr_t cmaddr
= (caddr_t
)arg
;
165 prnode_t
*pnp
= VTOP(vp
);
167 prnode_t
*xpnp
= NULL
;
171 size_t thingsize
= 0;
174 * For copyin()/copyout().
195 auxv_t auxv
[__KERN_NAUXV_IMPL
];
198 if (pnp
->pr_type
== PR_TMPL
)
199 return (prctioctl(pnp
, cmd
, arg
, flag
, cr
));
202 * Support for old /proc interface.
204 if (pnp
->pr_pidfile
!= NULL
) {
205 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
206 vp
= pnp
->pr_pidfile
;
208 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
211 if (pnp
->pr_type
!= PR_PIDFILE
&& pnp
->pr_type
!= PR_LWPIDFILE
)
215 * Fail ioctls which are logically "write" requests unless
216 * the user has write permission.
218 if ((flag
& FWRITE
) == 0 && isprwrioctl(cmd
))
222 * Perform any necessary copyin() operations before
223 * locking the process. Helps avoid deadlocks and
224 * improves performance.
226 * Also, detect invalid ioctl codes here to avoid
227 * locking a process unnnecessarily.
229 * Also, prepare to allocate space that will be needed below,
235 thingsize
= sizeof (proc_t
);
238 thingsize
= sizeof (user_t
);
258 case PIOCSXREG
: /* set extra registers */
259 case PIOCGXREG
: /* get extra registers */
263 thingsize
= (nsig
-1) * sizeof (struct sigaction
);
277 * We will need this below.
278 * Allocate it now, before locking the process.
280 xpnp
= prgetnode(vp
, PR_OPAGEDATA
);
286 #if defined(__i386) || defined(__amd64)
290 #endif /* __i386 || __amd64 */
293 case PIOCOPENM
: /* open mapped object for reading */
296 else if (copyin(cmaddr
, &un
.va
, sizeof (un
.va
)))
300 case PIOCRUN
: /* make lwp or process runnable */
302 un
.prrun
.pr_flags
= 0;
303 else if (copyin(cmaddr
, &un
.prrun
, sizeof (un
.prrun
)))
307 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
308 if (copyin(cmaddr
, &un
.lwpid
, sizeof (un
.lwpid
)))
312 case PIOCSTRACE
: /* set signal trace mask */
313 if (copyin(cmaddr
, &un
.smask
, sizeof (un
.smask
)))
317 case PIOCSSIG
: /* set current signal */
319 un
.info
.si_signo
= 0;
320 else if (copyin(cmaddr
, &un
.info
, sizeof (un
.info
)))
324 case PIOCKILL
: /* send signal */
325 case PIOCUNKILL
: /* delete a signal */
326 if (copyin(cmaddr
, &un
.signo
, sizeof (un
.signo
)))
330 case PIOCNICE
: /* set nice priority */
331 if (copyin(cmaddr
, &un
.nice
, sizeof (un
.nice
)))
335 case PIOCSENTRY
: /* set syscall entry bit mask */
336 case PIOCSEXIT
: /* set syscall exit bit mask */
337 if (copyin(cmaddr
, &un
.prmask
, sizeof (un
.prmask
)))
341 case PIOCSET
: /* set process flags */
342 case PIOCRESET
: /* reset process flags */
343 if (copyin(cmaddr
, &un
.flags
, sizeof (un
.flags
)))
347 case PIOCSREG
: /* set general registers */
348 if (copyin(cmaddr
, un
.regs
, sizeof (un
.regs
)))
352 case PIOCSFPREG
: /* set floating-point registers */
353 if (copyin(cmaddr
, &un
.fpregs
, sizeof (un
.fpregs
)))
357 case PIOCSHOLD
: /* set signal-hold mask */
358 if (copyin(cmaddr
, &un
.holdmask
, sizeof (un
.holdmask
)))
362 case PIOCSFAULT
: /* set mask of traced faults */
363 if (copyin(cmaddr
, &un
.fltmask
, sizeof (un
.fltmask
)))
377 * If we need kmem_alloc()d space then we allocate it now, before
378 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
379 * holding the process lock leads to deadlock with the clock thread.
380 * (The clock thread wakes up the pageout daemon to free up space.
381 * If the clock thread blocks behind us and we are sleeping waiting
382 * for space, then space may never become available.)
385 ASSERT(thing
== NULL
);
386 thing
= kmem_alloc(thingsize
, KM_SLEEP
);
396 case PIOCSXREG
: /* set extra registers */
398 * perform copyin before grabbing the process lock
401 if (copyin(cmaddr
, thing
, thingsize
)) {
402 kmem_free(thing
, thingsize
);
406 /* fall through... */
412 if ((error
= prlock(pnp
, zdisp
)) != 0) {
414 kmem_free(thing
, thingsize
);
420 pcp
= pnp
->pr_common
;
425 * Choose a thread/lwp for the operation.
427 if (zdisp
== ZNO
&& cmd
!= PIOCSTOP
&& cmd
!= PIOCWSTOP
) {
428 if (pnp
->pr_type
== PR_LWPIDFILE
&& cmd
!= PIOCLSTATUS
) {
432 t
= prchoose(p
); /* returns locked thread */
442 case PIOCGETPR
: /* read struct proc */
448 if (copyout(prp
, cmaddr
, sizeof (proc_t
)))
450 kmem_free(prp
, sizeof (proc_t
));
455 case PIOCGETU
: /* read u-area */
457 user_t
*userp
= thing
;
462 if (copyout(userp
, cmaddr
, sizeof (user_t
)))
464 kmem_free(userp
, sizeof (user_t
));
469 case PIOCOPENM
: /* open mapped object for reading */
470 error
= propenm(pnp
, cmaddr
, un
.va
, rvalp
, cr
);
471 /* propenm() called prunlock(pnp) */
474 case PIOCSTOP
: /* stop process or lwp from running */
475 case PIOCWSTOP
: /* wait for process or lwp to stop */
477 * Can't apply to a system process.
479 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
489 * If an lwp is waiting for itself or its process, don't wait.
490 * The stopped lwp would never see the fact that it is stopped.
492 if ((pnp
->pr_type
== PR_LWPIDFILE
)?
493 (pcp
->prc_thread
== curthread
) : (p
== curproc
)) {
494 if (cmd
== PIOCWSTOP
)
500 if ((error
= pr_wait_stop(pnp
, (time_t)0)) != 0)
501 break; /* pr_wait_stop() unlocked the process */
507 * Return process/lwp status information.
509 t
= pr_thread(pnp
); /* returns locked thread */
511 oprgetstatus(t
, &un
.prstat
, VTOZONE(vp
));
513 if (copyout(&un
.prstat
, cmaddr
, sizeof (un
.prstat
)))
518 case PIOCRUN
: /* make lwp or process runnable */
520 long flags
= un
.prrun
.pr_flags
;
523 * Cannot set an lwp running is it is not stopped.
524 * Also, no lwp other than the /proc agent lwp can
525 * be set running so long as the /proc agent lwp exists.
527 if ((!ISTOPPED(t
) && !VSTOPPED(t
) &&
528 !(t
->t_proc_flag
& TP_PRSTOP
)) ||
529 (p
->p_agenttp
!= NULL
&&
530 (t
!= p
->p_agenttp
|| pnp
->pr_type
!= PR_LWPIDFILE
))) {
536 if (flags
& (PRSHOLD
|PRSTRACE
|PRSFAULT
|PRSVADDR
))
537 prsetrun(t
, &un
.prrun
);
539 error
= pr_setrun(pnp
, prmaprunflags(flags
));
545 case PIOCLWPIDS
: /* get array of lwp identifiers */
552 Nlwp
= nlwp
= p
->p_lwpcnt
;
554 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (id_t
)) {
555 kmem_free(thing
, thingsize
);
559 thingsize
= (Nlwp
+1) * sizeof (id_t
);
560 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
570 if ((t
= p
->p_tlist
) != NULL
) {
572 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
576 } while ((t
= t
->t_forw
) != p
->p_tlist
);
581 if (copyout(Bidp
, cmaddr
, (Nlwp
+1) * sizeof (id_t
)))
583 kmem_free(Bidp
, (Nlwp
+1) * sizeof (id_t
));
587 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
593 if ((xvp
= prlwpnode(pnp
, un
.lwpid
)) == NULL
)
595 else if (error
= fassign(&xvp
, flag
& (FREAD
|FWRITE
), &n
)) {
602 case PIOCOPENPD
: /* return /proc page data file descriptor */
604 vnode_t
*xvp
= PTOV(xpnp
);
605 vnode_t
*dp
= pnp
->pr_parent
;
608 if (pnp
->pr_type
== PR_LWPIDFILE
) {
609 dp
= VTOP(dp
)->pr_parent
;
610 dp
= VTOP(dp
)->pr_parent
;
612 ASSERT(VTOP(dp
)->pr_type
== PR_PIDDIR
);
615 pcp
= pnp
->pr_pcommon
;
616 xpnp
->pr_ino
= ptoi(pcp
->prc_pid
);
617 xpnp
->pr_common
= pcp
;
618 xpnp
->pr_pcommon
= pcp
;
619 xpnp
->pr_parent
= dp
;
621 xpnp
->pr_next
= p
->p_plist
;
625 if (error
= fassign(&xvp
, FREAD
, &n
)) {
634 case PIOCGTRACE
: /* get signal trace mask */
635 prassignset(&un
.smask
, &p
->p_sigmask
);
637 if (copyout(&un
.smask
, cmaddr
, sizeof (un
.smask
)))
641 case PIOCSTRACE
: /* set signal trace mask */
642 prdelset(&un
.smask
, SIGKILL
);
643 prassignset(&p
->p_sigmask
, &un
.smask
);
644 if (!sigisempty(&p
->p_sigmask
))
645 p
->p_proc_flag
|= P_PR_TRACE
;
646 else if (prisempty(&p
->p_fltmask
)) {
648 if (up
->u_systrap
== 0)
649 p
->p_proc_flag
&= ~P_PR_TRACE
;
654 case PIOCSSIG
: /* set current signal */
655 error
= pr_setsig(pnp
, &un
.info
);
657 if (un
.info
.si_signo
== SIGKILL
&& error
== 0)
661 case PIOCKILL
: /* send signal */
663 int sig
= (int)un
.signo
;
665 error
= pr_kill(pnp
, sig
, cr
);
667 if (sig
== SIGKILL
&& error
== 0)
672 case PIOCUNKILL
: /* delete a signal */
673 error
= pr_unkill(pnp
, (int)un
.signo
);
677 case PIOCNICE
: /* set nice priority */
678 error
= pr_nice(p
, (int)un
.nice
, cr
);
682 case PIOCGENTRY
: /* get syscall entry bit mask */
683 case PIOCGEXIT
: /* get syscall exit bit mask */
685 if (cmd
== PIOCGENTRY
) {
686 prassignset(&un
.prmask
, &up
->u_entrymask
);
688 prassignset(&un
.prmask
, &up
->u_exitmask
);
691 if (copyout(&un
.prmask
, cmaddr
, sizeof (un
.prmask
)))
695 case PIOCSENTRY
: /* set syscall entry bit mask */
696 case PIOCSEXIT
: /* set syscall exit bit mask */
697 pr_setentryexit(p
, &un
.prmask
, cmd
== PIOCSENTRY
);
701 case PIOCSRLC
: /* obsolete: set running on last /proc close */
702 error
= pr_set(p
, prmapsetflags(PR_RLC
));
706 case PIOCRRLC
: /* obsolete: reset run-on-last-close flag */
707 error
= pr_unset(p
, prmapsetflags(PR_RLC
));
711 case PIOCSFORK
: /* obsolete: set inherit-on-fork flag */
712 error
= pr_set(p
, prmapsetflags(PR_FORK
));
716 case PIOCRFORK
: /* obsolete: reset inherit-on-fork flag */
717 error
= pr_unset(p
, prmapsetflags(PR_FORK
));
721 case PIOCSET
: /* set process flags */
722 error
= pr_set(p
, prmapsetflags(un
.flags
));
726 case PIOCRESET
: /* reset process flags */
727 error
= pr_unset(p
, prmapsetflags(un
.flags
));
731 case PIOCGREG
: /* get general registers */
732 if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
733 bzero(un
.regs
, sizeof (un
.regs
));
735 /* drop p_lock while touching the lwp's stack */
736 mutex_exit(&p
->p_lock
);
737 prgetprregs(lwp
, un
.regs
);
738 mutex_enter(&p
->p_lock
);
741 if (copyout(un
.regs
, cmaddr
, sizeof (un
.regs
)))
745 case PIOCSREG
: /* set general registers */
746 if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
749 /* drop p_lock while touching the lwp's stack */
750 mutex_exit(&p
->p_lock
);
751 prsetprregs(lwp
, un
.regs
, 0);
752 mutex_enter(&p
->p_lock
);
757 case PIOCGFPREG
: /* get floating-point registers */
760 error
= EINVAL
; /* No FP support */
764 if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
765 bzero(&un
.fpregs
, sizeof (un
.fpregs
));
767 /* drop p_lock while touching the lwp's stack */
768 mutex_exit(&p
->p_lock
);
769 prgetprfpregs(lwp
, &un
.fpregs
);
770 mutex_enter(&p
->p_lock
);
773 if (copyout(&un
.fpregs
, cmaddr
, sizeof (un
.fpregs
)))
777 case PIOCSFPREG
: /* set floating-point registers */
779 error
= EINVAL
; /* No FP support */
780 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
783 /* drop p_lock while touching the lwp's stack */
784 mutex_exit(&p
->p_lock
);
785 prsetprfpregs(lwp
, &un
.fpregs
);
786 mutex_enter(&p
->p_lock
);
791 case PIOCGXREGSIZE
: /* get the size of the extra registers */
796 xregsize
= prgetprxregsize(p
);
798 if (copyout(&xregsize
, cmaddr
, sizeof (xregsize
)))
802 error
= EINVAL
; /* No extra register support */
807 case PIOCGXREG
: /* get extra registers */
809 bzero(thing
, thingsize
);
810 if (t
->t_state
== TS_STOPPED
|| VSTOPPED(t
)) {
811 /* drop p_lock to touch the stack */
812 mutex_exit(&p
->p_lock
);
813 prgetprxregs(lwp
, thing
);
814 mutex_enter(&p
->p_lock
);
817 if (copyout(thing
, cmaddr
, thingsize
))
821 error
= EINVAL
; /* No extra register support */
824 kmem_free(thing
, thingsize
);
829 case PIOCSXREG
: /* set extra registers */
830 if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
833 error
= EINVAL
; /* No extra register support */
835 /* drop p_lock while touching the lwp's stack */
836 mutex_exit(&p
->p_lock
);
837 prsetprxregs(lwp
, thing
);
838 mutex_enter(&p
->p_lock
);
842 kmem_free(thing
, thingsize
);
847 case PIOCSTATUS
: /* get process/lwp status */
848 oprgetstatus(t
, &un
.prstat
, VTOZONE(vp
));
850 if (copyout(&un
.prstat
, cmaddr
, sizeof (un
.prstat
)))
854 case PIOCLSTATUS
: /* get status for process & all lwps */
861 nlwp
= Nlwp
= p
->p_lwpcnt
;
863 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (prstatus_t
)) {
864 kmem_free(thing
, thingsize
);
868 thingsize
= (Nlwp
+1) * sizeof (prstatus_t
);
869 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
879 oprgetstatus(t
, prsp
, VTOZONE(vp
));
882 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
885 oprgetstatus(t
, ++prsp
, VTOZONE(vp
));
886 } while ((t
= t
->t_forw
) != p
->p_tlist
);
889 if (copyout(Bprsp
, cmaddr
, (Nlwp
+1) * sizeof (prstatus_t
)))
892 kmem_free(Bprsp
, (Nlwp
+1) * sizeof (prstatus_t
));
896 case PIOCPSINFO
: /* get ps(1) information */
898 prpsinfo_t
*psp
= &un
.prps
;
901 (pnp
->pr_type
== PR_LWPIDFILE
)? pcp
->prc_thread
: NULL
);
904 if (copyout(&un
.prps
, cmaddr
, sizeof (un
.prps
)))
909 case PIOCMAXSIG
: /* get maximum signal number */
914 if (copyout(&n
, cmaddr
, sizeof (n
)))
919 case PIOCACTION
: /* get signal action structures */
922 struct sigaction
*sap
= thing
;
925 for (sig
= 1; sig
< nsig
; sig
++)
926 prgetaction(p
, up
, sig
, &sap
[sig
-1]);
928 if (copyout(sap
, cmaddr
, (nsig
-1) * sizeof (struct sigaction
)))
930 kmem_free(sap
, (nsig
-1) * sizeof (struct sigaction
));
935 case PIOCGHOLD
: /* get signal-hold mask */
936 schedctl_finish_sigblock(t
);
937 sigktou(&t
->t_hold
, &un
.holdmask
);
939 if (copyout(&un
.holdmask
, cmaddr
, sizeof (un
.holdmask
)))
943 case PIOCSHOLD
: /* set signal-hold mask */
944 pr_sethold(pnp
, &un
.holdmask
);
948 case PIOCNMAP
: /* get number of memory mappings */
951 struct as
*as
= p
->p_as
;
953 if ((p
->p_flag
& SSYS
) || as
== &kas
)
956 mutex_exit(&p
->p_lock
);
957 AS_LOCK_ENTER(as
, RW_WRITER
);
960 mutex_enter(&p
->p_lock
);
963 if (copyout(&n
, cmaddr
, sizeof (int)))
968 case PIOCMAP
: /* get memory map information */
971 struct as
*as
= p
->p_as
;
973 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
977 mutex_exit(&p
->p_lock
);
978 AS_LOCK_ENTER(as
, RW_WRITER
);
979 error
= oprgetmap(p
, &iolhead
);
981 mutex_enter(&p
->p_lock
);
984 error
= pr_iol_copyout_and_free(&iolhead
,
988 * The procfs PIOCMAP ioctl returns an all-zero buffer
989 * to indicate the end of the prmap[] array.
990 * Append it to whatever has already been copied out.
992 bzero(&un
.prmap
, sizeof (un
.prmap
));
993 if (!error
&& copyout(&un
.prmap
, cmaddr
, sizeof (un
.prmap
)))
999 case PIOCGFAULT
: /* get mask of traced faults */
1000 prassignset(&un
.fltmask
, &p
->p_fltmask
);
1002 if (copyout(&un
.fltmask
, cmaddr
, sizeof (un
.fltmask
)))
1006 case PIOCSFAULT
: /* set mask of traced faults */
1007 pr_setfault(p
, &un
.fltmask
);
1011 case PIOCCFAULT
: /* clear current fault */
1012 lwp
->lwp_curflt
= 0;
1016 case PIOCCRED
: /* get process credentials */
1020 mutex_enter(&p
->p_crlock
);
1022 un
.prcred
.pr_euid
= crgetuid(cp
);
1023 un
.prcred
.pr_ruid
= crgetruid(cp
);
1024 un
.prcred
.pr_suid
= crgetsuid(cp
);
1025 un
.prcred
.pr_egid
= crgetgid(cp
);
1026 un
.prcred
.pr_rgid
= crgetrgid(cp
);
1027 un
.prcred
.pr_sgid
= crgetsgid(cp
);
1028 un
.prcred
.pr_ngroups
= crgetngroups(cp
);
1029 mutex_exit(&p
->p_crlock
);
1032 if (copyout(&un
.prcred
, cmaddr
, sizeof (un
.prcred
)))
1037 case PIOCGROUPS
: /* get supplementary groups */
1041 mutex_enter(&p
->p_crlock
);
1044 mutex_exit(&p
->p_crlock
);
1047 if (copyout(crgetgroups(cp
), cmaddr
,
1048 MAX(crgetngroups(cp
), 1) * sizeof (gid_t
)))
1054 case PIOCUSAGE
: /* get usage info */
1057 * For an lwp file descriptor, return just the lwp usage.
1058 * For a process file descriptor, return total usage,
1059 * all current lwps plus all defunct lwps.
1061 prhusage_t
*pup
= &un
.prhusage
;
1064 bzero(pup
, sizeof (*pup
));
1065 pup
->pr_tstamp
= gethrtime();
1067 if (pnp
->pr_type
== PR_LWPIDFILE
) {
1068 t
= pcp
->prc_thread
;
1074 pup
->pr_count
= p
->p_defunct
;
1075 pup
->pr_create
= p
->p_mstart
;
1076 pup
->pr_term
= p
->p_mterm
;
1078 pup
->pr_rtime
= p
->p_mlreal
;
1079 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1080 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1081 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1082 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1083 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1084 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1085 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1086 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1087 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1088 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1090 pup
->pr_minf
= p
->p_ru
.minflt
;
1091 pup
->pr_majf
= p
->p_ru
.majflt
;
1092 pup
->pr_nswap
= p
->p_ru
.nswap
;
1093 pup
->pr_inblk
= p
->p_ru
.inblock
;
1094 pup
->pr_oublk
= p
->p_ru
.oublock
;
1095 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1096 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1097 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1098 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1099 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1100 pup
->pr_sysc
= p
->p_ru
.sysc
;
1101 pup
->pr_ioch
= p
->p_ru
.ioch
;
1104 * Add the usage information for each active lwp.
1106 if ((t
= p
->p_tlist
) != NULL
&&
1107 !(pcp
->prc_flags
& PRC_DESTROY
)) {
1109 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
1112 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1118 upup
= kmem_zalloc(sizeof (*upup
), KM_SLEEP
);
1119 prcvtusage(&un
.prhusage
, upup
);
1120 if (copyout(upup
, cmaddr
, sizeof (*upup
)))
1122 kmem_free(upup
, sizeof (*upup
));
1127 case PIOCLUSAGE
: /* get detailed usage info */
1136 nlwp
= Nlwp
= (pcp
->prc_flags
& PRC_DESTROY
)? 0 : p
->p_lwpcnt
;
1138 if (thing
&& thingsize
!=
1139 sizeof (prhusage_t
) + (Nlwp
+1) * sizeof (prusage_t
)) {
1140 kmem_free(thing
, thingsize
);
1143 if (thing
== NULL
) {
1144 thingsize
= sizeof (prhusage_t
) +
1145 (Nlwp
+1) * sizeof (prusage_t
);
1146 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
1148 if (thing
== NULL
) {
1154 upup
= Bupup
= (prusage_t
*)(pup
+ 1);
1156 ASSERT(p
== pcp
->prc_proc
);
1158 curtime
= gethrtime();
1161 * First the summation over defunct lwps.
1163 bzero(pup
, sizeof (*pup
));
1164 pup
->pr_count
= p
->p_defunct
;
1165 pup
->pr_tstamp
= curtime
;
1166 pup
->pr_create
= p
->p_mstart
;
1167 pup
->pr_term
= p
->p_mterm
;
1169 pup
->pr_rtime
= p
->p_mlreal
;
1170 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1171 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1172 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1173 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1174 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1175 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1176 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1177 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1178 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1179 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1181 pup
->pr_minf
= p
->p_ru
.minflt
;
1182 pup
->pr_majf
= p
->p_ru
.majflt
;
1183 pup
->pr_nswap
= p
->p_ru
.nswap
;
1184 pup
->pr_inblk
= p
->p_ru
.inblock
;
1185 pup
->pr_oublk
= p
->p_ru
.oublock
;
1186 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1187 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1188 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1189 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1190 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1191 pup
->pr_sysc
= p
->p_ru
.sysc
;
1192 pup
->pr_ioch
= p
->p_ru
.ioch
;
1194 prcvtusage(pup
, upup
);
1197 * Fill one prusage struct for each active lwp.
1199 if ((t
= p
->p_tlist
) != NULL
&&
1200 !(pcp
->prc_flags
& PRC_DESTROY
)) {
1202 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
1207 prcvtusage(pup
, upup
);
1208 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1213 if (copyout(Bupup
, cmaddr
, (Nlwp
+1) * sizeof (prusage_t
)))
1215 kmem_free(thing
, thingsize
);
1220 case PIOCNAUXV
: /* get number of aux vector entries */
1222 int n
= __KERN_NAUXV_IMPL
;
1225 if (copyout(&n
, cmaddr
, sizeof (int)))
1230 case PIOCAUXV
: /* get aux vector (see sys/auxv.h) */
1233 bcopy(up
->u_auxv
, un
.auxv
,
1234 __KERN_NAUXV_IMPL
* sizeof (auxv_t
));
1236 if (copyout(un
.auxv
, cmaddr
,
1237 __KERN_NAUXV_IMPL
* sizeof (auxv_t
)))
1242 #if defined(__i386) || defined(__amd64)
1243 case PIOCNLDT
: /* get number of LDT entries */
1247 mutex_exit(&p
->p_lock
);
1248 mutex_enter(&p
->p_ldtlock
);
1250 mutex_exit(&p
->p_ldtlock
);
1251 mutex_enter(&p
->p_lock
);
1253 if (copyout(&n
, cmaddr
, sizeof (n
)))
1258 case PIOCLDT
: /* get LDT entries */
1263 mutex_exit(&p
->p_lock
);
1264 mutex_enter(&p
->p_ldtlock
);
1267 if (thing
&& thingsize
!= (n
+1) * sizeof (*ssd
)) {
1268 kmem_free(thing
, thingsize
);
1271 if (thing
== NULL
) {
1272 thingsize
= (n
+1) * sizeof (*ssd
);
1273 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
1275 if (thing
== NULL
) {
1276 mutex_exit(&p
->p_ldtlock
);
1277 mutex_enter(&p
->p_lock
);
1286 mutex_exit(&p
->p_ldtlock
);
1287 mutex_enter(&p
->p_lock
);
1290 /* mark the end of the list with a null entry */
1291 bzero(&ssd
[n
], sizeof (*ssd
));
1292 if (copyout(ssd
, cmaddr
, (n
+1) * sizeof (*ssd
)))
1294 kmem_free(ssd
, (n
+1) * sizeof (*ssd
));
1297 #endif /* __i386 || __amd64 */
1307 ASSERT(thing
== NULL
);
1308 ASSERT(xpnp
== NULL
);
1312 #ifdef _SYSCALL32_IMPL
1314 static int oprgetmap32(proc_t
*, list_t
*);
1317 oprgetstatus32(kthread_t
*t
, prstatus32_t
*sp
, zone_t
*zp
)
1319 proc_t
*p
= ttoproc(t
);
1320 klwp_t
*lwp
= ttolwp(t
);
1325 ASSERT(MUTEX_HELD(&p
->p_lock
));
1328 bzero(sp
, sizeof (*sp
));
1330 if (t
->t_state
== TS_STOPPED
) {
1331 flags
|= PR_STOPPED
;
1332 if ((t
->t_schedflag
& TS_PSTART
) == 0)
1334 } else if (VSTOPPED(t
)) {
1335 flags
|= PR_STOPPED
|PR_ISTOP
;
1337 if (!(flags
& PR_ISTOP
) && (t
->t_proc_flag
& TP_PRSTOP
))
1339 if (lwp
->lwp_asleep
)
1341 if (p
->p_proc_flag
& P_PR_FORK
)
1343 if (p
->p_proc_flag
& P_PR_RUNLCL
)
1345 if (p
->p_proc_flag
& P_PR_KILLCL
)
1347 if (p
->p_proc_flag
& P_PR_ASYNC
)
1349 if (p
->p_proc_flag
& P_PR_BPTADJ
)
1351 if (p
->p_proc_flag
& P_PR_PTRACE
)
1352 flags
|= PR_PCOMPAT
;
1353 if (t
->t_proc_flag
& TP_MSACCT
)
1355 sp
->pr_flags
= flags
;
1357 sp
->pr_why
= PR_REQUESTED
;
1360 sp
->pr_why
= t
->t_whystop
;
1361 sp
->pr_what
= t
->t_whatstop
;
1364 if (t
->t_whystop
== PR_FAULTED
) {
1365 siginfo_kto32(&lwp
->lwp_siginfo
, &sp
->pr_info
);
1366 if (t
->t_whatstop
== FLTPAGE
)
1367 sp
->pr_info
.si_addr
=
1368 (caddr32_t
)(uintptr_t)lwp
->lwp_siginfo
.si_addr
;
1369 } else if (lwp
->lwp_curinfo
)
1370 siginfo_kto32(&lwp
->lwp_curinfo
->sq_info
, &sp
->pr_info
);
1372 if (SI_FROMUSER(&lwp
->lwp_siginfo
) && zp
->zone_id
!= GLOBAL_ZONEID
&&
1373 sp
->pr_info
.si_zoneid
!= zp
->zone_id
) {
1374 sp
->pr_info
.si_pid
= zp
->zone_zsched
->p_pid
;
1375 sp
->pr_info
.si_uid
= 0;
1376 sp
->pr_info
.si_ctid
= -1;
1377 sp
->pr_info
.si_zoneid
= zp
->zone_id
;
1380 sp
->pr_cursig
= lwp
->lwp_cursig
;
1381 prassignset(&sp
->pr_sigpend
, &p
->p_sig
);
1382 prassignset(&sp
->pr_lwppend
, &t
->t_sig
);
1383 schedctl_finish_sigblock(t
);
1384 prassignset(&sp
->pr_sighold
, &t
->t_hold
);
1385 sp
->pr_altstack
.ss_sp
=
1386 (caddr32_t
)(uintptr_t)lwp
->lwp_sigaltstack
.ss_sp
;
1387 sp
->pr_altstack
.ss_size
= (size32_t
)lwp
->lwp_sigaltstack
.ss_size
;
1388 sp
->pr_altstack
.ss_flags
= (int32_t)lwp
->lwp_sigaltstack
.ss_flags
;
1389 prgetaction32(p
, up
, lwp
->lwp_cursig
, &sp
->pr_action
);
1390 sp
->pr_pid
= p
->p_pid
;
1391 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
1392 (p
->p_flag
& SZONETOP
)) {
1393 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
1395 * Inside local zones, fake zsched's pid as parent pids for
1396 * processes which reference processes outside of the zone.
1398 sp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
1400 sp
->pr_ppid
= p
->p_ppid
;
1402 sp
->pr_pgrp
= p
->p_pgrp
;
1403 sp
->pr_sid
= p
->p_sessp
->s_sid
;
1404 hrt2ts32(mstate_aggr_state(p
, LMS_USER
), &sp
->pr_utime
);
1405 hrt2ts32(mstate_aggr_state(p
, LMS_SYSTEM
), &sp
->pr_stime
);
1406 TICK_TO_TIMESTRUC32(p
->p_cutime
, &sp
->pr_cutime
);
1407 TICK_TO_TIMESTRUC32(p
->p_cstime
, &sp
->pr_cstime
);
1408 (void) strncpy(sp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
1409 sizeof (sp
->pr_clname
) - 1);
1410 sp
->pr_who
= t
->t_tid
;
1411 sp
->pr_nlwp
= p
->p_lwpcnt
;
1412 sp
->pr_brkbase
= (caddr32_t
)(uintptr_t)p
->p_brkbase
;
1413 sp
->pr_brksize
= (size32_t
)p
->p_brksize
;
1414 sp
->pr_stkbase
= (caddr32_t
)(uintptr_t)prgetstackbase(p
);
1415 sp
->pr_stksize
= (size32_t
)p
->p_stksize
;
1416 sp
->pr_oldcontext
= (caddr32_t
)lwp
->lwp_oldcontext
;
1417 sp
->pr_processor
= t
->t_cpu
->cpu_id
;
1418 sp
->pr_bind
= t
->t_bind_cpu
;
1421 * Fetch the current instruction, if not a system process.
1422 * We don't attempt this unless the lwp is stopped.
1424 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
1425 sp
->pr_flags
|= (PR_ISSYS
|PR_PCINVAL
);
1426 else if (!(flags
& PR_STOPPED
))
1427 sp
->pr_flags
|= PR_PCINVAL
;
1428 else if (!prfetchinstr(lwp
, &instr
))
1429 sp
->pr_flags
|= PR_PCINVAL
;
1431 sp
->pr_instr
= (uint32_t)instr
;
1434 * Drop p_lock while touching the lwp's stack.
1436 mutex_exit(&p
->p_lock
);
1438 sp
->pr_flags
|= PR_STEP
;
1439 if ((flags
& (PR_STOPPED
|PR_ASLEEP
)) && t
->t_sysnum
) {
1443 sp
->pr_syscall
= get_syscall32_args(lwp
,
1444 (int *)sp
->pr_sysarg
, &i
);
1445 sp
->pr_nsysarg
= (short)i
;
1446 if (t
->t_whystop
== PR_SYSEXIT
&& t
->t_sysnum
== SYS_execve
) {
1447 sp
->pr_sysarg
[0] = 0;
1448 sp
->pr_sysarg
[1] = (caddr32_t
)up
->u_argv
;
1449 sp
->pr_sysarg
[2] = (caddr32_t
)up
->u_envp
;
1450 for (i
= 0, auxp
= up
->u_auxv
;
1451 i
< sizeof (up
->u_auxv
) / sizeof (up
->u_auxv
[0]);
1453 if (auxp
->a_type
== AT_SUN_EXECNAME
) {
1456 (uintptr_t)auxp
->a_un
.a_ptr
;
1462 if ((flags
& PR_STOPPED
) || t
== curthread
)
1463 prgetprregs32(lwp
, sp
->pr_reg
);
1464 mutex_enter(&p
->p_lock
);
1468 oprgetpsinfo32(proc_t
*p
, prpsinfo32_t
*psp
, kthread_t
*tp
)
1475 int retval
, niceval
;
1478 hrtime_t hrutime
, hrstime
, cur_time
;
1480 ASSERT(MUTEX_HELD(&p
->p_lock
));
1482 bzero(psp
, sizeof (*psp
));
1484 if ((t
= tp
) == NULL
)
1485 t
= prchoose(p
); /* returns locked thread */
1489 /* kludge: map thread state enum into process state enum */
1494 state
= VSTOPPED(t
) ? TS_STOPPED
: t
->t_state
;
1499 case TS_SLEEP
: state
= SSLEEP
; break;
1500 case TS_RUN
: state
= SRUN
; break;
1501 case TS_ONPROC
: state
= SONPROC
; break;
1502 case TS_ZOMB
: state
= SZOMB
; break;
1503 case TS_STOPPED
: state
= SSTOP
; break;
1504 default: state
= 0; break;
1507 case SSLEEP
: c
= 'S'; break;
1508 case SRUN
: c
= 'R'; break;
1509 case SZOMB
: c
= 'Z'; break;
1510 case SSTOP
: c
= 'T'; break;
1511 case SIDL
: c
= 'I'; break;
1512 case SONPROC
: c
= 'O'; break;
1514 case SXBRK
: c
= 'X'; break;
1516 default: c
= '?'; break;
1518 psp
->pr_state
= state
;
1520 psp
->pr_zomb
= (state
== SZOMB
);
1522 * only export SSYS and SMSACCT; everything else is off-limits to
1525 psp
->pr_flag
= p
->p_flag
& (SSYS
| SMSACCT
);
1527 mutex_enter(&p
->p_crlock
);
1529 psp
->pr_uid
= crgetruid(cred
);
1530 psp
->pr_gid
= crgetrgid(cred
);
1531 psp
->pr_euid
= crgetuid(cred
);
1532 psp
->pr_egid
= crgetgid(cred
);
1533 mutex_exit(&p
->p_crlock
);
1535 psp
->pr_pid
= p
->p_pid
;
1536 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
1537 (p
->p_flag
& SZONETOP
)) {
1538 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
1540 * Inside local zones, fake zsched's pid as parent pids for
1541 * processes which reference processes outside of the zone.
1543 psp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
1545 psp
->pr_ppid
= p
->p_ppid
;
1547 psp
->pr_pgrp
= p
->p_pgrp
;
1548 psp
->pr_sid
= p
->p_sessp
->s_sid
;
1549 psp
->pr_addr
= 0; /* cannot represent 64-bit addr in 32 bits */
1550 hrutime
= mstate_aggr_state(p
, LMS_USER
);
1551 hrstime
= mstate_aggr_state(p
, LMS_SYSTEM
);
1552 hrt2ts32(hrutime
+ hrstime
, &psp
->pr_time
);
1553 TICK_TO_TIMESTRUC32(p
->p_cutime
+ p
->p_cstime
, &psp
->pr_ctime
);
1554 switch (p
->p_model
) {
1555 case DATAMODEL_ILP32
:
1556 psp
->pr_dmodel
= PR_MODEL_ILP32
;
1558 case DATAMODEL_LP64
:
1559 psp
->pr_dmodel
= PR_MODEL_LP64
;
1562 if (state
== SZOMB
|| t
== NULL
) {
1563 int wcode
= p
->p_wcode
; /* must be atomic read */
1566 psp
->pr_wstat
= wstat(wcode
, p
->p_wdata
);
1567 psp
->pr_lttydev
= PRNODEV32
;
1568 psp
->pr_ottydev
= (o_dev_t
)PRNODEV32
;
1574 psp
->pr_wchan
= 0; /* cannot represent in 32 bits */
1575 psp
->pr_pri
= t
->t_pri
;
1576 (void) strncpy(psp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
1577 sizeof (psp
->pr_clname
) - 1);
1578 retval
= CL_DONICE(t
, NULL
, 0, &niceval
);
1580 psp
->pr_oldpri
= v
.v_maxsyspri
- psp
->pr_pri
;
1581 psp
->pr_nice
= niceval
+ NZERO
;
1589 extern dev_t rwsconsdev
, rconsdev
, uconsdev
;
1591 * If the controlling terminal is the real
1592 * or workstation console device, map to what the
1593 * user thinks is the console device. Handle case when
1594 * rwsconsdev or rconsdev is set to NODEV for Starfire.
1596 if ((d
== rwsconsdev
|| d
== rconsdev
) && d
!= NODEV
)
1600 (void) cmpldev(&psp
->pr_lttydev
, d
);
1601 psp
->pr_ottydev
= cmpdev(d
);
1602 TIMESPEC_TO_TIMESPEC32(&psp
->pr_start
, &up
->u_start
);
1603 bcopy(up
->u_comm
, psp
->pr_fname
,
1604 MIN(sizeof (up
->u_comm
), sizeof (psp
->pr_fname
)-1));
1605 bcopy(up
->u_psargs
, psp
->pr_psargs
,
1606 MIN(PRARGSZ
-1, PSARGSZ
));
1607 psp
->pr_syscall
= t
->t_sysnum
;
1608 psp
->pr_argc
= up
->u_argc
;
1609 psp
->pr_argv
= (caddr32_t
)up
->u_argv
;
1610 psp
->pr_envp
= (caddr32_t
)up
->u_envp
;
1612 /* compute %cpu for the lwp or process */
1614 if ((t
= tp
) == NULL
)
1616 cur_time
= gethrtime_unscaled();
1618 pct
+= cpu_update_pct(t
, cur_time
);
1619 if (tp
!= NULL
) /* just do the one lwp */
1621 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1623 psp
->pr_pctcpu
= prgetpctcpu(pct
);
1624 psp
->pr_cpu
= (psp
->pr_pctcpu
*100 + 0x6000) >> 15; /* [0..99] */
1625 if (psp
->pr_cpu
> 99)
1628 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
1633 mutex_exit(&p
->p_lock
);
1634 AS_LOCK_ENTER(as
, RW_READER
);
1635 psp
->pr_size
= (size32_t
)btopr(as
->a_resvsize
);
1636 psp
->pr_rssize
= (size32_t
)rm_asrss(as
);
1637 psp
->pr_pctmem
= rm_pctmemory(as
);
1639 mutex_enter(&p
->p_lock
);
1642 psp
->pr_bysize
= (size32_t
)ptob(psp
->pr_size
);
1643 psp
->pr_byrssize
= (size32_t
)ptob(psp
->pr_rssize
);
1646 * If we are looking at an LP64 process, zero out
1647 * the fields that cannot be represented in ILP32.
1649 if (p
->p_model
!= DATAMODEL_ILP32
) {
1653 psp
->pr_byrssize
= 0;
1668 caller_context_t
*ct
)
1670 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
1671 caddr_t cmaddr
= (caddr_t
)arg
;
1676 prnode_t
*pnp
= VTOP(vp
);
1678 prnode_t
*xpnp
= NULL
;
1682 size_t thingsize
= 0;
1685 * For copyin()/copyout().
1693 prstatus32_t prstat
;
1699 prfpregset32_t fpregs
;
1704 prusage32_t prusage
;
1705 prhusage_t prhusage
;
1706 ioc_prmap32_t prmap
;
1707 auxv32_t auxv
[__KERN_NAUXV_IMPL
];
1711 * Native objects for internal use.
1730 prhusage_t prhusage
;
1731 auxv_t auxv
[__KERN_NAUXV_IMPL
];
1734 if (pnp
->pr_type
== PR_TMPL
)
1735 return (prctioctl(pnp
, cmd
, arg
, flag
, cr
));
1738 * Support for old /proc interface.
1740 if (pnp
->pr_pidfile
!= NULL
) {
1741 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
1742 vp
= pnp
->pr_pidfile
;
1744 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
1747 if (pnp
->pr_type
!= PR_PIDFILE
&& pnp
->pr_type
!= PR_LWPIDFILE
)
1751 * Fail ioctls which are logically "write" requests unless
1752 * the user has write permission.
1754 if ((flag
& FWRITE
) == 0 && isprwrioctl(cmd
))
1758 * Perform any necessary copyin() operations before
1759 * locking the process. Helps avoid deadlocks and
1760 * improves performance.
1762 * Also, detect invalid ioctl codes here to avoid
1763 * locking a process unnnecessarily.
1765 * Also, prepare to allocate space that will be needed below,
1771 thingsize
= sizeof (proc_t
);
1774 thingsize
= sizeof (user_t
);
1794 case PIOCSXREG
: /* set extra registers */
1795 case PIOCGXREG
: /* get extra registers */
1796 #if defined(__sparc)
1797 thingsize
= sizeof (prxregset_t
);
1803 thingsize
= (nsig
-1) * sizeof (struct sigaction32
);
1817 * We will need this below.
1818 * Allocate it now, before locking the process.
1820 xpnp
= prgetnode(vp
, PR_OPAGEDATA
);
1826 #if defined(__i386) || defined(__i386_COMPAT)
1830 #endif /* __i386 || __i386_COMPAT */
1832 #if defined(__sparc)
1834 thingsize
= sizeof (gwindows32_t
);
1836 #endif /* __sparc */
1838 case PIOCOPENM
: /* open mapped object for reading */
1840 un32
.va
= (uintptr_t)NULL
;
1841 else if (copyin(cmaddr
, &un32
.va
, sizeof (un32
.va
)))
1845 case PIOCRUN
: /* make lwp or process runnable */
1847 un32
.prrun
.pr_flags
= 0;
1848 else if (copyin(cmaddr
, &un32
.prrun
, sizeof (un32
.prrun
)))
1852 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
1853 if (copyin(cmaddr
, &un32
.lwpid
, sizeof (un32
.lwpid
)))
1857 case PIOCSTRACE
: /* set signal trace mask */
1858 if (copyin(cmaddr
, &un32
.smask
, sizeof (un32
.smask
)))
1862 case PIOCSSIG
: /* set current signal */
1864 un32
.info
.si_signo
= 0;
1865 else if (copyin(cmaddr
, &un32
.info
, sizeof (un32
.info
)))
1869 case PIOCKILL
: /* send signal */
1870 case PIOCUNKILL
: /* delete a signal */
1871 if (copyin(cmaddr
, &un32
.signo
, sizeof (un32
.signo
)))
1875 case PIOCNICE
: /* set nice priority */
1876 if (copyin(cmaddr
, &un32
.nice
, sizeof (un32
.nice
)))
1880 case PIOCSENTRY
: /* set syscall entry bit mask */
1881 case PIOCSEXIT
: /* set syscall exit bit mask */
1882 if (copyin(cmaddr
, &un32
.prmask
, sizeof (un32
.prmask
)))
1886 case PIOCSET
: /* set process flags */
1887 case PIOCRESET
: /* reset process flags */
1888 if (copyin(cmaddr
, &un32
.flags
, sizeof (un32
.flags
)))
1892 case PIOCSREG
: /* set general registers */
1893 if (copyin(cmaddr
, un32
.regs
, sizeof (un32
.regs
)))
1897 case PIOCSFPREG
: /* set floating-point registers */
1898 if (copyin(cmaddr
, &un32
.fpregs
, sizeof (un32
.fpregs
)))
1902 case PIOCSHOLD
: /* set signal-hold mask */
1903 if (copyin(cmaddr
, &un32
.holdmask
, sizeof (un32
.holdmask
)))
1907 case PIOCSFAULT
: /* set mask of traced faults */
1908 if (copyin(cmaddr
, &un32
.fltmask
, sizeof (un32
.fltmask
)))
1922 * If we need kmem_alloc()d space then we allocate it now, before
1923 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
1924 * holding the process lock leads to deadlock with the clock thread.
1925 * (The clock thread wakes up the pageout daemon to free up space.
1926 * If the clock thread blocks behind us and we are sleeping waiting
1927 * for space, then space may never become available.)
1930 ASSERT(thing
== NULL
);
1931 thing
= kmem_alloc(thingsize
, KM_SLEEP
);
1941 case PIOCSXREG
: /* set extra registers */
1943 * perform copyin before grabbing the process lock
1946 if (copyin(cmaddr
, thing
, thingsize
)) {
1947 kmem_free(thing
, thingsize
);
1951 /* fall through... */
1957 if ((error
= prlock(pnp
, zdisp
)) != 0) {
1959 kmem_free(thing
, thingsize
);
1965 pcp
= pnp
->pr_common
;
1970 * Choose a thread/lwp for the operation.
1972 if (zdisp
== ZNO
&& cmd
!= PIOCSTOP
&& cmd
!= PIOCWSTOP
) {
1973 if (pnp
->pr_type
== PR_LWPIDFILE
&& cmd
!= PIOCLSTATUS
) {
1974 t
= pcp
->prc_thread
;
1977 t
= prchoose(p
); /* returns locked thread */
1987 case PIOCGETPR
: /* read struct proc */
1989 proc_t
*prp
= thing
;
1993 if (copyout(prp
, cmaddr
, sizeof (proc_t
)))
1995 kmem_free(prp
, sizeof (proc_t
));
2000 case PIOCGETU
: /* read u-area */
2002 user_t
*userp
= thing
;
2007 if (copyout(userp
, cmaddr
, sizeof (user_t
)))
2009 kmem_free(userp
, sizeof (user_t
));
2014 case PIOCOPENM
: /* open mapped object for reading */
2015 if (PROCESS_NOT_32BIT(p
) && cmaddr
!= NULL
) {
2020 error
= propenm(pnp
, cmaddr
,
2021 (caddr_t
)(uintptr_t)un32
.va
, rvalp
, cr
);
2022 /* propenm() called prunlock(pnp) */
2025 case PIOCSTOP
: /* stop process or lwp from running */
2026 case PIOCWSTOP
: /* wait for process or lwp to stop */
2028 * Can't apply to a system process.
2030 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
2036 if (cmd
== PIOCSTOP
)
2040 * If an lwp is waiting for itself or its process, don't wait.
2041 * The lwp will never see the fact that itself is stopped.
2043 if ((pnp
->pr_type
== PR_LWPIDFILE
)?
2044 (pcp
->prc_thread
== curthread
) : (p
== curproc
)) {
2045 if (cmd
== PIOCWSTOP
)
2051 if ((error
= pr_wait_stop(pnp
, (time_t)0)) != 0)
2052 break; /* pr_wait_stop() unlocked the process */
2056 else if (PROCESS_NOT_32BIT(p
)) {
2061 * Return process/lwp status information.
2063 t
= pr_thread(pnp
); /* returns locked thread */
2065 oprgetstatus32(t
, &un32
.prstat
, VTOZONE(vp
));
2067 if (copyout(&un32
.prstat
, cmaddr
, sizeof (un32
.prstat
)))
2072 case PIOCRUN
: /* make lwp or process runnable */
2074 long flags
= un32
.prrun
.pr_flags
;
2077 * Cannot set an lwp running is it is not stopped.
2078 * Also, no lwp other than the /proc agent lwp can
2079 * be set running so long as the /proc agent lwp exists.
2081 if ((!ISTOPPED(t
) && !VSTOPPED(t
) &&
2082 !(t
->t_proc_flag
& TP_PRSTOP
)) ||
2083 (p
->p_agenttp
!= NULL
&&
2084 (t
!= p
->p_agenttp
|| pnp
->pr_type
!= PR_LWPIDFILE
))) {
2090 if ((flags
& PRSVADDR
) && PROCESS_NOT_32BIT(p
)) {
2096 if (flags
& (PRSHOLD
|PRSTRACE
|PRSFAULT
|PRSVADDR
)) {
2097 un
.prrun
.pr_flags
= (int)flags
;
2098 un
.prrun
.pr_trace
= un32
.prrun
.pr_trace
;
2099 un
.prrun
.pr_sighold
= un32
.prrun
.pr_sighold
;
2100 un
.prrun
.pr_fault
= un32
.prrun
.pr_fault
;
2102 (caddr_t
)(uintptr_t)un32
.prrun
.pr_vaddr
;
2103 prsetrun(t
, &un
.prrun
);
2106 error
= pr_setrun(pnp
, prmaprunflags(flags
));
2112 case PIOCLWPIDS
: /* get array of lwp identifiers */
2119 Nlwp
= nlwp
= p
->p_lwpcnt
;
2121 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (id_t
)) {
2122 kmem_free(thing
, thingsize
);
2125 if (thing
== NULL
) {
2126 thingsize
= (Nlwp
+1) * sizeof (id_t
);
2127 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2129 if (thing
== NULL
) {
2137 if ((t
= p
->p_tlist
) != NULL
) {
2139 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2143 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2148 if (copyout(Bidp
, cmaddr
, (Nlwp
+1) * sizeof (id_t
)))
2150 kmem_free(Bidp
, (Nlwp
+1) * sizeof (id_t
));
2154 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
2160 if ((xvp
= prlwpnode(pnp
, un32
.lwpid
)) == NULL
)
2162 else if (error
= fassign(&xvp
, flag
& (FREAD
|FWRITE
), &n
)) {
2169 case PIOCOPENPD
: /* return /proc page data file descriptor */
2171 vnode_t
*xvp
= PTOV(xpnp
);
2172 vnode_t
*dp
= pnp
->pr_parent
;
2175 if (PROCESS_NOT_32BIT(p
)) {
2183 if (pnp
->pr_type
== PR_LWPIDFILE
) {
2184 dp
= VTOP(dp
)->pr_parent
;
2185 dp
= VTOP(dp
)->pr_parent
;
2187 ASSERT(VTOP(dp
)->pr_type
== PR_PIDDIR
);
2190 pcp
= pnp
->pr_pcommon
;
2191 xpnp
->pr_ino
= ptoi(pcp
->prc_pid
);
2192 xpnp
->pr_common
= pcp
;
2193 xpnp
->pr_pcommon
= pcp
;
2194 xpnp
->pr_parent
= dp
;
2196 xpnp
->pr_next
= p
->p_plist
;
2200 if (error
= fassign(&xvp
, FREAD
, &n
)) {
2209 case PIOCGTRACE
: /* get signal trace mask */
2210 prassignset(&un32
.smask
, &p
->p_sigmask
);
2212 if (copyout(&un32
.smask
, cmaddr
, sizeof (un32
.smask
)))
2216 case PIOCSTRACE
: /* set signal trace mask */
2217 prdelset(&un32
.smask
, SIGKILL
);
2218 prassignset(&p
->p_sigmask
, &un32
.smask
);
2219 if (!sigisempty(&p
->p_sigmask
))
2220 p
->p_proc_flag
|= P_PR_TRACE
;
2221 else if (prisempty(&p
->p_fltmask
)) {
2223 if (up
->u_systrap
== 0)
2224 p
->p_proc_flag
&= ~P_PR_TRACE
;
2229 case PIOCSSIG
: /* set current signal */
2230 if (un32
.info
.si_signo
!= 0 && PROCESS_NOT_32BIT(p
)) {
2234 bzero(&un
.info
, sizeof (un
.info
));
2235 siginfo_32tok(&un32
.info
, (k_siginfo_t
*)&un
.info
);
2236 error
= pr_setsig(pnp
, &un
.info
);
2238 if (un32
.info
.si_signo
== SIGKILL
&& error
== 0)
2243 case PIOCKILL
: /* send signal */
2244 error
= pr_kill(pnp
, un32
.signo
, cr
);
2246 if (un32
.signo
== SIGKILL
&& error
== 0)
2250 case PIOCUNKILL
: /* delete a signal */
2251 error
= pr_unkill(pnp
, un32
.signo
);
2255 case PIOCNICE
: /* set nice priority */
2256 error
= pr_nice(p
, un32
.nice
, cr
);
2260 case PIOCGENTRY
: /* get syscall entry bit mask */
2261 case PIOCGEXIT
: /* get syscall exit bit mask */
2263 if (cmd
== PIOCGENTRY
) {
2264 prassignset(&un32
.prmask
, &up
->u_entrymask
);
2266 prassignset(&un32
.prmask
, &up
->u_exitmask
);
2269 if (copyout(&un32
.prmask
, cmaddr
, sizeof (un32
.prmask
)))
2273 case PIOCSENTRY
: /* set syscall entry bit mask */
2274 case PIOCSEXIT
: /* set syscall exit bit mask */
2275 pr_setentryexit(p
, &un32
.prmask
, cmd
== PIOCSENTRY
);
2279 case PIOCSRLC
: /* obsolete: set running on last /proc close */
2280 error
= pr_set(p
, prmapsetflags(PR_RLC
));
2284 case PIOCRRLC
: /* obsolete: reset run-on-last-close flag */
2285 error
= pr_unset(p
, prmapsetflags(PR_RLC
));
2289 case PIOCSFORK
: /* obsolete: set inherit-on-fork flag */
2290 error
= pr_set(p
, prmapsetflags(PR_FORK
));
2294 case PIOCRFORK
: /* obsolete: reset inherit-on-fork flag */
2295 error
= pr_unset(p
, prmapsetflags(PR_FORK
));
2299 case PIOCSET
: /* set process flags */
2300 error
= pr_set(p
, prmapsetflags((long)un32
.flags
));
2304 case PIOCRESET
: /* reset process flags */
2305 error
= pr_unset(p
, prmapsetflags((long)un32
.flags
));
2309 case PIOCGREG
: /* get general registers */
2310 if (PROCESS_NOT_32BIT(p
))
2312 else if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
2313 bzero(un32
.regs
, sizeof (un32
.regs
));
2315 /* drop p_lock while touching the lwp's stack */
2316 mutex_exit(&p
->p_lock
);
2317 prgetprregs32(lwp
, un32
.regs
);
2318 mutex_enter(&p
->p_lock
);
2322 copyout(un32
.regs
, cmaddr
, sizeof (un32
.regs
)))
2326 case PIOCSREG
: /* set general registers */
2327 if (PROCESS_NOT_32BIT(p
))
2329 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
2332 /* drop p_lock while touching the lwp's stack */
2333 mutex_exit(&p
->p_lock
);
2334 prgregset_32ton(lwp
, un32
.regs
, un
.regs
);
2335 prsetprregs(lwp
, un
.regs
, 0);
2336 mutex_enter(&p
->p_lock
);
2341 case PIOCGFPREG
: /* get floating-point registers */
2343 error
= EINVAL
; /* No FP support */
2344 else if (PROCESS_NOT_32BIT(p
))
2346 else if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
2347 bzero(&un32
.fpregs
, sizeof (un32
.fpregs
));
2349 /* drop p_lock while touching the lwp's stack */
2350 mutex_exit(&p
->p_lock
);
2351 prgetprfpregs32(lwp
, &un32
.fpregs
);
2352 mutex_enter(&p
->p_lock
);
2356 copyout(&un32
.fpregs
, cmaddr
, sizeof (un32
.fpregs
)))
2360 case PIOCSFPREG
: /* set floating-point registers */
2362 error
= EINVAL
; /* No FP support */
2363 else if (PROCESS_NOT_32BIT(p
))
2365 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
2368 /* drop p_lock while touching the lwp's stack */
2369 mutex_exit(&p
->p_lock
);
2370 prsetprfpregs32(lwp
, &un32
.fpregs
);
2371 mutex_enter(&p
->p_lock
);
2376 case PIOCGXREGSIZE
: /* get the size of the extra registers */
2381 xregsize
= prgetprxregsize(p
);
2383 if (copyout(&xregsize
, cmaddr
, sizeof (xregsize
)))
2387 error
= EINVAL
; /* No extra register support */
2392 case PIOCGXREG
: /* get extra registers */
2393 if (PROCESS_NOT_32BIT(p
))
2395 else if (!prhasx(p
))
2396 error
= EINVAL
; /* No extra register support */
2398 bzero(thing
, thingsize
);
2399 if (t
->t_state
== TS_STOPPED
|| VSTOPPED(t
)) {
2400 /* drop p_lock to touch the stack */
2401 mutex_exit(&p
->p_lock
);
2402 prgetprxregs(lwp
, thing
);
2403 mutex_enter(&p
->p_lock
);
2408 copyout(thing
, cmaddr
, thingsize
))
2411 kmem_free(thing
, thingsize
);
2416 case PIOCSXREG
: /* set extra registers */
2417 if (PROCESS_NOT_32BIT(p
))
2419 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
2421 else if (!prhasx(p
))
2422 error
= EINVAL
; /* No extra register support */
2424 /* drop p_lock while touching the lwp's stack */
2425 mutex_exit(&p
->p_lock
);
2426 prsetprxregs(lwp
, thing
);
2427 mutex_enter(&p
->p_lock
);
2431 kmem_free(thing
, thingsize
);
2436 case PIOCSTATUS
: /* get process/lwp status */
2437 if (PROCESS_NOT_32BIT(p
)) {
2442 oprgetstatus32(t
, &un32
.prstat
, VTOZONE(vp
));
2444 if (copyout(&un32
.prstat
, cmaddr
, sizeof (un32
.prstat
)))
2448 case PIOCLSTATUS
: /* get status for process & all lwps */
2452 prstatus32_t
*Bprsp
;
2455 if (PROCESS_NOT_32BIT(p
)) {
2458 kmem_free(thing
, thingsize
);
2465 nlwp
= Nlwp
= p
->p_lwpcnt
;
2467 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (prstatus32_t
)) {
2468 kmem_free(thing
, thingsize
);
2471 if (thing
== NULL
) {
2472 thingsize
= (Nlwp
+1) * sizeof (prstatus32_t
);
2473 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2475 if (thing
== NULL
) {
2480 Bprsp
= (prstatus32_t
*)thing
;
2483 oprgetstatus32(t
, prsp
, VTOZONE(vp
));
2486 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2489 oprgetstatus32(t
, ++prsp
, VTOZONE(vp
));
2490 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2493 if (copyout(Bprsp
, cmaddr
, (Nlwp
+1) * sizeof (prstatus32_t
)))
2496 kmem_free(Bprsp
, (Nlwp
+ 1) * sizeof (prstatus32_t
));
2500 case PIOCPSINFO
: /* get ps(1) information */
2502 prpsinfo32_t
*psp
= &un32
.prps
;
2504 oprgetpsinfo32(p
, psp
,
2505 (pnp
->pr_type
== PR_LWPIDFILE
)? pcp
->prc_thread
: NULL
);
2508 if (copyout(&un32
.prps
, cmaddr
, sizeof (un32
.prps
)))
2513 case PIOCMAXSIG
: /* get maximum signal number */
2518 if (copyout(&n
, cmaddr
, sizeof (int)))
2523 case PIOCACTION
: /* get signal action structures */
2526 struct sigaction32
*sap
= thing
;
2528 if (PROCESS_NOT_32BIT(p
))
2532 for (sig
= 1; sig
< nsig
; sig
++)
2533 prgetaction32(p
, up
, sig
, &sap
[sig
-1]);
2537 copyout(sap
, cmaddr
, (nsig
-1)*sizeof (struct sigaction32
)))
2539 kmem_free(sap
, (nsig
-1)*sizeof (struct sigaction32
));
2544 case PIOCGHOLD
: /* get signal-hold mask */
2545 schedctl_finish_sigblock(t
);
2546 sigktou(&t
->t_hold
, &un32
.holdmask
);
2548 if (copyout(&un32
.holdmask
, cmaddr
, sizeof (un32
.holdmask
)))
2552 case PIOCSHOLD
: /* set signal-hold mask */
2553 pr_sethold(pnp
, &un32
.holdmask
);
2557 case PIOCNMAP
: /* get number of memory mappings */
2560 struct as
*as
= p
->p_as
;
2562 if ((p
->p_flag
& SSYS
) || as
== &kas
)
2565 mutex_exit(&p
->p_lock
);
2566 AS_LOCK_ENTER(as
, RW_WRITER
);
2569 mutex_enter(&p
->p_lock
);
2572 if (copyout(&n
, cmaddr
, sizeof (int)))
2577 case PIOCMAP
: /* get memory map information */
2580 struct as
*as
= p
->p_as
;
2582 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
2585 } else if (PROCESS_NOT_32BIT(p
)) {
2589 mutex_exit(&p
->p_lock
);
2590 AS_LOCK_ENTER(as
, RW_WRITER
);
2591 error
= oprgetmap32(p
, &iolhead
);
2593 mutex_enter(&p
->p_lock
);
2596 error
= pr_iol_copyout_and_free(&iolhead
,
2600 * The procfs PIOCMAP ioctl returns an all-zero buffer
2601 * to indicate the end of the prmap[] array.
2602 * Append it to whatever has already been copied out.
2604 bzero(&un32
.prmap
, sizeof (un32
.prmap
));
2606 copyout(&un32
.prmap
, cmaddr
, sizeof (un32
.prmap
)))
2611 case PIOCGFAULT
: /* get mask of traced faults */
2612 prassignset(&un32
.fltmask
, &p
->p_fltmask
);
2614 if (copyout(&un32
.fltmask
, cmaddr
, sizeof (un32
.fltmask
)))
2618 case PIOCSFAULT
: /* set mask of traced faults */
2619 pr_setfault(p
, &un32
.fltmask
);
2623 case PIOCCFAULT
: /* clear current fault */
2624 lwp
->lwp_curflt
= 0;
2628 case PIOCCRED
: /* get process credentials */
2632 mutex_enter(&p
->p_crlock
);
2634 un32
.prcred
.pr_euid
= crgetuid(cp
);
2635 un32
.prcred
.pr_ruid
= crgetruid(cp
);
2636 un32
.prcred
.pr_suid
= crgetsuid(cp
);
2637 un32
.prcred
.pr_egid
= crgetgid(cp
);
2638 un32
.prcred
.pr_rgid
= crgetrgid(cp
);
2639 un32
.prcred
.pr_sgid
= crgetsgid(cp
);
2640 un32
.prcred
.pr_ngroups
= crgetngroups(cp
);
2641 mutex_exit(&p
->p_crlock
);
2644 if (copyout(&un32
.prcred
, cmaddr
, sizeof (un32
.prcred
)))
2649 case PIOCGROUPS
: /* get supplementary groups */
2653 mutex_enter(&p
->p_crlock
);
2656 mutex_exit(&p
->p_crlock
);
2659 if (copyout(crgetgroups(cp
), cmaddr
,
2660 MAX(crgetngroups(cp
), 1) * sizeof (gid_t
)))
2666 case PIOCUSAGE
: /* get usage info */
2669 * For an lwp file descriptor, return just the lwp usage.
2670 * For a process file descriptor, return total usage,
2671 * all current lwps plus all defunct lwps.
2673 prhusage_t
*pup
= &un32
.prhusage
;
2676 bzero(pup
, sizeof (*pup
));
2677 pup
->pr_tstamp
= gethrtime();
2679 if (pnp
->pr_type
== PR_LWPIDFILE
) {
2680 t
= pcp
->prc_thread
;
2686 pup
->pr_count
= p
->p_defunct
;
2687 pup
->pr_create
= p
->p_mstart
;
2688 pup
->pr_term
= p
->p_mterm
;
2690 pup
->pr_rtime
= p
->p_mlreal
;
2691 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2692 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2693 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2694 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2695 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2696 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2697 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2698 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2699 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2700 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2702 pup
->pr_minf
= p
->p_ru
.minflt
;
2703 pup
->pr_majf
= p
->p_ru
.majflt
;
2704 pup
->pr_nswap
= p
->p_ru
.nswap
;
2705 pup
->pr_inblk
= p
->p_ru
.inblock
;
2706 pup
->pr_oublk
= p
->p_ru
.oublock
;
2707 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2708 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2709 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2710 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2711 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2712 pup
->pr_sysc
= p
->p_ru
.sysc
;
2713 pup
->pr_ioch
= p
->p_ru
.ioch
;
2716 * Add the usage information for each active lwp.
2718 if ((t
= p
->p_tlist
) != NULL
&&
2719 !(pcp
->prc_flags
& PRC_DESTROY
)) {
2721 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2724 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2730 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
2731 prcvtusage32(pup
, upup
);
2732 if (copyout(upup
, cmaddr
, sizeof (*upup
)))
2734 kmem_free(upup
, sizeof (*upup
));
2739 case PIOCLUSAGE
: /* get detailed usage info */
2748 nlwp
= Nlwp
= (pcp
->prc_flags
& PRC_DESTROY
)? 0 : p
->p_lwpcnt
;
2750 if (thing
&& thingsize
!=
2751 sizeof (prhusage_t
) + (Nlwp
+1) * sizeof (prusage32_t
)) {
2752 kmem_free(thing
, thingsize
);
2755 if (thing
== NULL
) {
2756 thingsize
= sizeof (prhusage_t
) +
2757 (Nlwp
+1) * sizeof (prusage32_t
);
2758 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2760 if (thing
== NULL
) {
2765 pup
= (prhusage_t
*)thing
;
2766 upup
= Bupup
= (prusage32_t
*)(pup
+ 1);
2768 ASSERT(p
== pcp
->prc_proc
);
2770 curtime
= gethrtime();
2773 * First the summation over defunct lwps.
2775 bzero(pup
, sizeof (*pup
));
2776 pup
->pr_count
= p
->p_defunct
;
2777 pup
->pr_tstamp
= curtime
;
2778 pup
->pr_create
= p
->p_mstart
;
2779 pup
->pr_term
= p
->p_mterm
;
2781 pup
->pr_rtime
= p
->p_mlreal
;
2782 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2783 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2784 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2785 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2786 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2787 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2788 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2789 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2790 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2791 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2793 pup
->pr_minf
= p
->p_ru
.minflt
;
2794 pup
->pr_majf
= p
->p_ru
.majflt
;
2795 pup
->pr_nswap
= p
->p_ru
.nswap
;
2796 pup
->pr_inblk
= p
->p_ru
.inblock
;
2797 pup
->pr_oublk
= p
->p_ru
.oublock
;
2798 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2799 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2800 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2801 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2802 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2803 pup
->pr_sysc
= p
->p_ru
.sysc
;
2804 pup
->pr_ioch
= p
->p_ru
.ioch
;
2806 prcvtusage32(pup
, upup
);
2809 * Fill one prusage struct for each active lwp.
2811 if ((t
= p
->p_tlist
) != NULL
&&
2812 !(pcp
->prc_flags
& PRC_DESTROY
)) {
2814 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2819 prcvtusage32(pup
, upup
);
2820 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2825 if (copyout(Bupup
, cmaddr
, (Nlwp
+1) * sizeof (prusage32_t
)))
2827 kmem_free(thing
, thingsize
);
2832 case PIOCNAUXV
: /* get number of aux vector entries */
2834 int n
= __KERN_NAUXV_IMPL
;
2837 if (copyout(&n
, cmaddr
, sizeof (int)))
2842 case PIOCAUXV
: /* get aux vector (see sys/auxv.h) */
2846 if (PROCESS_NOT_32BIT(p
)) {
2851 for (i
= 0; i
< __KERN_NAUXV_IMPL
; i
++) {
2852 un32
.auxv
[i
].a_type
= up
->u_auxv
[i
].a_type
;
2853 un32
.auxv
[i
].a_un
.a_val
=
2854 (int32_t)up
->u_auxv
[i
].a_un
.a_val
;
2857 if (copyout(un32
.auxv
, cmaddr
,
2858 __KERN_NAUXV_IMPL
* sizeof (auxv32_t
)))
2864 #if defined(__i386) || defined(__i386_COMPAT)
2865 case PIOCNLDT
: /* get number of LDT entries */
2869 mutex_exit(&p
->p_lock
);
2870 mutex_enter(&p
->p_ldtlock
);
2872 mutex_exit(&p
->p_ldtlock
);
2873 mutex_enter(&p
->p_lock
);
2875 if (copyout(&n
, cmaddr
, sizeof (n
)))
2880 case PIOCLDT
: /* get LDT entries */
2885 mutex_exit(&p
->p_lock
);
2886 mutex_enter(&p
->p_ldtlock
);
2889 if (thing
&& thingsize
!= (n
+1) * sizeof (*ssd
)) {
2890 kmem_free(thing
, thingsize
);
2893 if (thing
== NULL
) {
2894 thingsize
= (n
+1) * sizeof (*ssd
);
2895 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2897 if (thing
== NULL
) {
2898 mutex_exit(&p
->p_ldtlock
);
2899 mutex_enter(&p
->p_lock
);
2908 mutex_exit(&p
->p_ldtlock
);
2909 mutex_enter(&p
->p_lock
);
2912 /* mark the end of the list with a null entry */
2913 bzero(&ssd
[n
], sizeof (*ssd
));
2914 if (copyout(ssd
, cmaddr
, (n
+1) * sizeof (*ssd
)))
2916 kmem_free(ssd
, (n
+1) * sizeof (*ssd
));
2919 #endif /* __i386 || __i386_COMPAT */
2921 #if defined(__sparc)
2922 case PIOCGWIN
: /* get gwindows_t (see sys/reg.h) */
2924 gwindows32_t
*gwp
= thing
;
2926 if (PROCESS_NOT_32BIT(p
)) {
2930 /* drop p->p_lock while touching the stack */
2931 mutex_exit(&p
->p_lock
);
2932 bzero(gwp
, sizeof (*gwp
));
2933 prgetwindows32(lwp
, gwp
);
2934 mutex_enter(&p
->p_lock
);
2936 if (copyout(gwp
, cmaddr
, sizeof (*gwp
)))
2939 kmem_free(gwp
, sizeof (*gwp
));
2943 #endif /* __sparc */
2952 ASSERT(thing
== NULL
);
2953 ASSERT(xpnp
== NULL
);
2956 #endif /* _SYSCALL32_IMPL */
2959 * Distinguish "writeable" ioctl requests from others.
2962 isprwrioctl(int cmd
)
2992 * Map the ioctl() interface run flags to the new interface run flags.
2995 prmaprunflags(long flags
)
2997 ulong_t newflags
= 0;
3001 if (flags
& PRCFAULT
)
3005 if (flags
& PRSABORT
)
3013 * Map the ioctl() interface settable mode flags to the new interface flags.
3016 prmapsetflags(long flags
)
3021 (PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_MSACCT|PR_PCOMPAT)
3023 if (flags
& ~ALLFLAGS
)
3024 newflags
= 0xffff; /* forces EINVAL */
3025 if (flags
& PR_FORK
)
3026 newflags
|= (0x00100000 | 0x08000000);
3028 newflags
|= 0x00200000;
3030 newflags
|= 0x00400000;
3031 if (flags
& PR_ASYNC
)
3032 newflags
|= 0x00800000;
3033 if (flags
& PR_MSACCT
)
3034 newflags
|= 0x01000000;
3035 if (flags
& PR_BPTADJ
)
3036 newflags
|= 0x02000000;
3037 if (flags
& PR_PCOMPAT
)
3038 newflags
|= 0x04000000;
3043 * Apply PIOCRUN options specific to the ioctl() interface.
3046 prsetrun(kthread_t
*t
, prrun_t
*prp
)
3048 proc_t
*p
= ttoproc(t
);
3049 klwp_t
*lwp
= ttolwp(t
);
3050 long flags
= prp
->pr_flags
;
3051 user_t
*up
= PTOU(p
);
3053 ASSERT(MUTEX_HELD(&p
->p_lock
));
3055 if (flags
& PRSHOLD
) {
3056 schedctl_finish_sigblock(t
);
3057 sigutok(&prp
->pr_sighold
, &t
->t_hold
);
3058 t
->t_sig_check
= 1; /* so ISSIG will be done */
3060 if (flags
& PRSTRACE
) {
3061 prdelset(&prp
->pr_trace
, SIGKILL
);
3062 prassignset(&p
->p_sigmask
, &prp
->pr_trace
);
3063 if (!sigisempty(&p
->p_sigmask
))
3064 p
->p_proc_flag
|= P_PR_TRACE
;
3065 else if (prisempty(&p
->p_fltmask
)) {
3066 if (up
->u_systrap
== 0)
3067 p
->p_proc_flag
&= ~P_PR_TRACE
;
3070 if (flags
& PRSFAULT
) {
3071 prassignset(&p
->p_fltmask
, &prp
->pr_fault
);
3072 if (!prisempty(&p
->p_fltmask
))
3073 p
->p_proc_flag
|= P_PR_TRACE
;
3074 else if (sigisempty(&p
->p_sigmask
)) {
3075 if (up
->u_systrap
== 0)
3076 p
->p_proc_flag
&= ~P_PR_TRACE
;
3080 * prsvaddr() must be called before prstep() because
3081 * stepping can depend on the current value of the PC.
3082 * We drop p_lock while touching the lwp's registers (on stack).
3084 if (flags
& PRSVADDR
) {
3085 mutex_exit(&p
->p_lock
);
3086 prsvaddr(lwp
, prp
->pr_vaddr
);
3087 mutex_enter(&p
->p_lock
);
3092 * Common code for PIOCOPENM
3093 * Returns with the process unlocked.
3096 propenm(prnode_t
*pnp
, caddr_t cmaddr
, caddr_t va
, int *rvalp
, cred_t
*cr
)
3098 proc_t
*p
= pnp
->pr_common
->prc_proc
;
3099 struct as
*as
= p
->p_as
;
3106 * By fiat, a system process has no address space.
3108 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
3110 } else if (cmaddr
) {
3112 * We drop p_lock before grabbing the address
3113 * space lock in order to avoid a deadlock with
3114 * the clock thread. The process will not
3115 * disappear and its address space will not
3116 * change because it is marked P_PR_LOCK.
3118 mutex_exit(&p
->p_lock
);
3119 AS_LOCK_ENTER(as
, RW_READER
);
3120 seg
= as_segat(as
, va
);
3122 seg
->s_ops
== &segvn_ops
&&
3123 segop_getvp(seg
, va
, &xvp
) == 0 &&
3125 xvp
->v_type
== VREG
) {
3131 mutex_enter(&p
->p_lock
);
3132 } else if ((xvp
= p
->p_exec
) == NULL
) {
3141 if ((error
= fop_access(xvp
, VREAD
, 0, cr
, NULL
)) == 0)
3142 error
= fassign(&xvp
, FREAD
, &n
);
3154 * Return old version of process/lwp status.
3155 * The u-block is mapped in by this routine and unmapped at the end.
3158 oprgetstatus(kthread_t
*t
, prstatus_t
*sp
, zone_t
*zp
)
3160 proc_t
*p
= ttoproc(t
);
3161 klwp_t
*lwp
= ttolwp(t
);
3166 ASSERT(MUTEX_HELD(&p
->p_lock
));
3169 bzero(sp
, sizeof (*sp
));
3171 if (t
->t_state
== TS_STOPPED
) {
3172 flags
|= PR_STOPPED
;
3173 if ((t
->t_schedflag
& TS_PSTART
) == 0)
3175 } else if (VSTOPPED(t
)) {
3176 flags
|= PR_STOPPED
|PR_ISTOP
;
3178 if (!(flags
& PR_ISTOP
) && (t
->t_proc_flag
& TP_PRSTOP
))
3180 if (lwp
->lwp_asleep
)
3182 if (p
->p_proc_flag
& P_PR_FORK
)
3184 if (p
->p_proc_flag
& P_PR_RUNLCL
)
3186 if (p
->p_proc_flag
& P_PR_KILLCL
)
3188 if (p
->p_proc_flag
& P_PR_ASYNC
)
3190 if (p
->p_proc_flag
& P_PR_BPTADJ
)
3192 if (p
->p_proc_flag
& P_PR_PTRACE
)
3193 flags
|= PR_PCOMPAT
;
3194 if (t
->t_proc_flag
& TP_MSACCT
)
3196 sp
->pr_flags
= flags
;
3198 sp
->pr_why
= PR_REQUESTED
;
3201 sp
->pr_why
= t
->t_whystop
;
3202 sp
->pr_what
= t
->t_whatstop
;
3205 if (t
->t_whystop
== PR_FAULTED
)
3206 bcopy(&lwp
->lwp_siginfo
,
3207 &sp
->pr_info
, sizeof (k_siginfo_t
));
3208 else if (lwp
->lwp_curinfo
)
3209 bcopy(&lwp
->lwp_curinfo
->sq_info
,
3210 &sp
->pr_info
, sizeof (k_siginfo_t
));
3212 if (SI_FROMUSER(&lwp
->lwp_siginfo
) && zp
->zone_id
!= GLOBAL_ZONEID
&&
3213 sp
->pr_info
.si_zoneid
!= zp
->zone_id
) {
3214 sp
->pr_info
.si_pid
= zp
->zone_zsched
->p_pid
;
3215 sp
->pr_info
.si_uid
= 0;
3216 sp
->pr_info
.si_ctid
= -1;
3217 sp
->pr_info
.si_zoneid
= zp
->zone_id
;
3220 sp
->pr_cursig
= lwp
->lwp_cursig
;
3221 prassignset(&sp
->pr_sigpend
, &p
->p_sig
);
3222 prassignset(&sp
->pr_lwppend
, &t
->t_sig
);
3223 schedctl_finish_sigblock(t
);
3224 prassignset(&sp
->pr_sighold
, &t
->t_hold
);
3225 sp
->pr_altstack
= lwp
->lwp_sigaltstack
;
3226 prgetaction(p
, up
, lwp
->lwp_cursig
, &sp
->pr_action
);
3227 sp
->pr_pid
= p
->p_pid
;
3228 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
3229 (p
->p_flag
& SZONETOP
)) {
3230 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
3232 * Inside local zones, fake zsched's pid as parent pids for
3233 * processes which reference processes outside of the zone.
3235 sp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
3237 sp
->pr_ppid
= p
->p_ppid
;
3239 sp
->pr_pgrp
= p
->p_pgrp
;
3240 sp
->pr_sid
= p
->p_sessp
->s_sid
;
3241 hrt2ts(mstate_aggr_state(p
, LMS_USER
), &sp
->pr_utime
);
3242 hrt2ts(mstate_aggr_state(p
, LMS_SYSTEM
), &sp
->pr_stime
);
3243 TICK_TO_TIMESTRUC(p
->p_cutime
, &sp
->pr_cutime
);
3244 TICK_TO_TIMESTRUC(p
->p_cstime
, &sp
->pr_cstime
);
3245 (void) strncpy(sp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
3246 sizeof (sp
->pr_clname
) - 1);
3247 sp
->pr_who
= t
->t_tid
;
3248 sp
->pr_nlwp
= p
->p_lwpcnt
;
3249 sp
->pr_brkbase
= p
->p_brkbase
;
3250 sp
->pr_brksize
= p
->p_brksize
;
3251 sp
->pr_stkbase
= prgetstackbase(p
);
3252 sp
->pr_stksize
= p
->p_stksize
;
3253 sp
->pr_oldcontext
= (struct ucontext
*)lwp
->lwp_oldcontext
;
3254 sp
->pr_processor
= t
->t_cpu
->cpu_id
;
3255 sp
->pr_bind
= t
->t_bind_cpu
;
3258 * Fetch the current instruction, if not a system process.
3259 * We don't attempt this unless the lwp is stopped.
3261 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
3262 sp
->pr_flags
|= (PR_ISSYS
|PR_PCINVAL
);
3263 else if (!(flags
& PR_STOPPED
))
3264 sp
->pr_flags
|= PR_PCINVAL
;
3265 else if (!prfetchinstr(lwp
, &instr
))
3266 sp
->pr_flags
|= PR_PCINVAL
;
3268 sp
->pr_instr
= instr
;
3271 * Drop p_lock while touching the lwp's stack.
3273 mutex_exit(&p
->p_lock
);
3275 sp
->pr_flags
|= PR_STEP
;
3276 if ((flags
& (PR_STOPPED
|PR_ASLEEP
)) && t
->t_sysnum
) {
3280 sp
->pr_syscall
= get_syscall_args(lwp
,
3281 (long *)sp
->pr_sysarg
, &i
);
3282 sp
->pr_nsysarg
= (short)i
;
3283 if (t
->t_whystop
== PR_SYSEXIT
&& t
->t_sysnum
== SYS_execve
) {
3284 sp
->pr_sysarg
[0] = 0;
3285 sp
->pr_sysarg
[1] = (uintptr_t)up
->u_argv
;
3286 sp
->pr_sysarg
[2] = (uintptr_t)up
->u_envp
;
3287 for (i
= 0, auxp
= up
->u_auxv
;
3288 i
< sizeof (up
->u_auxv
) / sizeof (up
->u_auxv
[0]);
3290 if (auxp
->a_type
== AT_SUN_EXECNAME
) {
3292 (uintptr_t)auxp
->a_un
.a_ptr
;
3298 if ((flags
& PR_STOPPED
) || t
== curthread
)
3299 prgetprregs(lwp
, sp
->pr_reg
);
3300 mutex_enter(&p
->p_lock
);
3304 * Return old version of information used by ps(1).
3307 oprgetpsinfo(proc_t
*p
, prpsinfo_t
*psp
, kthread_t
*tp
)
3314 int retval
, niceval
;
3317 hrtime_t hrutime
, hrstime
, cur_time
;
3319 ASSERT(MUTEX_HELD(&p
->p_lock
));
3321 bzero(psp
, sizeof (*psp
));
3323 if ((t
= tp
) == NULL
)
3324 t
= prchoose(p
); /* returns locked thread */
3328 /* kludge: map thread state enum into process state enum */
3333 state
= VSTOPPED(t
) ? TS_STOPPED
: t
->t_state
;
3338 case TS_SLEEP
: state
= SSLEEP
; break;
3339 case TS_RUN
: state
= SRUN
; break;
3340 case TS_ONPROC
: state
= SONPROC
; break;
3341 case TS_ZOMB
: state
= SZOMB
; break;
3342 case TS_STOPPED
: state
= SSTOP
; break;
3343 default: state
= 0; break;
3346 case SSLEEP
: c
= 'S'; break;
3347 case SRUN
: c
= 'R'; break;
3348 case SZOMB
: c
= 'Z'; break;
3349 case SSTOP
: c
= 'T'; break;
3350 case SIDL
: c
= 'I'; break;
3351 case SONPROC
: c
= 'O'; break;
3353 case SXBRK
: c
= 'X'; break;
3355 default: c
= '?'; break;
3357 psp
->pr_state
= state
;
3359 psp
->pr_zomb
= (state
== SZOMB
);
3361 * only export SSYS and SMSACCT; everything else is off-limits to
3364 psp
->pr_flag
= p
->p_flag
& (SSYS
| SMSACCT
);
3366 mutex_enter(&p
->p_crlock
);
3368 psp
->pr_uid
= crgetruid(cred
);
3369 psp
->pr_gid
= crgetrgid(cred
);
3370 psp
->pr_euid
= crgetuid(cred
);
3371 psp
->pr_egid
= crgetgid(cred
);
3372 mutex_exit(&p
->p_crlock
);
3374 psp
->pr_pid
= p
->p_pid
;
3375 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
3376 (p
->p_flag
& SZONETOP
)) {
3377 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
3379 * Inside local zones, fake zsched's pid as parent pids for
3380 * processes which reference processes outside of the zone.
3382 psp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
3384 psp
->pr_ppid
= p
->p_ppid
;
3386 psp
->pr_pgrp
= p
->p_pgrp
;
3387 psp
->pr_sid
= p
->p_sessp
->s_sid
;
3388 psp
->pr_addr
= prgetpsaddr(p
);
3389 hrutime
= mstate_aggr_state(p
, LMS_USER
);
3390 hrstime
= mstate_aggr_state(p
, LMS_SYSTEM
);
3391 hrt2ts(hrutime
+ hrstime
, &psp
->pr_time
);
3392 TICK_TO_TIMESTRUC(p
->p_cutime
+ p
->p_cstime
, &psp
->pr_ctime
);
3393 switch (p
->p_model
) {
3394 case DATAMODEL_ILP32
:
3395 psp
->pr_dmodel
= PR_MODEL_ILP32
;
3397 case DATAMODEL_LP64
:
3398 psp
->pr_dmodel
= PR_MODEL_LP64
;
3401 if (state
== SZOMB
|| t
== NULL
) {
3402 int wcode
= p
->p_wcode
; /* must be atomic read */
3405 psp
->pr_wstat
= wstat(wcode
, p
->p_wdata
);
3406 psp
->pr_lttydev
= PRNODEV
;
3407 psp
->pr_ottydev
= (o_dev_t
)PRNODEV
;
3413 psp
->pr_wchan
= t
->t_wchan
;
3414 psp
->pr_pri
= t
->t_pri
;
3415 (void) strncpy(psp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
3416 sizeof (psp
->pr_clname
) - 1);
3417 retval
= CL_DONICE(t
, NULL
, 0, &niceval
);
3419 psp
->pr_oldpri
= v
.v_maxsyspri
- psp
->pr_pri
;
3420 psp
->pr_nice
= niceval
+ NZERO
;
3428 extern dev_t rwsconsdev
, rconsdev
, uconsdev
;
3430 * If the controlling terminal is the real
3431 * or workstation console device, map to what the
3432 * user thinks is the console device. Handle case when
3433 * rwsconsdev or rconsdev is set to NODEV for Starfire.
3435 if ((d
== rwsconsdev
|| d
== rconsdev
) && d
!= NODEV
)
3439 psp
->pr_lttydev
= (d
== NODEV
) ? PRNODEV
: d
;
3440 psp
->pr_ottydev
= cmpdev(d
);
3441 psp
->pr_start
= up
->u_start
;
3442 bcopy(up
->u_comm
, psp
->pr_fname
,
3443 MIN(sizeof (up
->u_comm
), sizeof (psp
->pr_fname
)-1));
3444 bcopy(up
->u_psargs
, psp
->pr_psargs
,
3445 MIN(PRARGSZ
-1, PSARGSZ
));
3446 psp
->pr_syscall
= t
->t_sysnum
;
3447 psp
->pr_argc
= up
->u_argc
;
3448 psp
->pr_argv
= (char **)up
->u_argv
;
3449 psp
->pr_envp
= (char **)up
->u_envp
;
3451 /* compute %cpu for the lwp or process */
3453 if ((t
= tp
) == NULL
)
3455 cur_time
= gethrtime_unscaled();
3457 pct
+= cpu_update_pct(t
, cur_time
);
3458 if (tp
!= NULL
) /* just do the one lwp */
3460 } while ((t
= t
->t_forw
) != p
->p_tlist
);
3462 psp
->pr_pctcpu
= prgetpctcpu(pct
);
3463 psp
->pr_cpu
= (psp
->pr_pctcpu
*100 + 0x6000) >> 15; /* [0..99] */
3464 if (psp
->pr_cpu
> 99)
3467 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
3472 mutex_exit(&p
->p_lock
);
3473 AS_LOCK_ENTER(as
, RW_READER
);
3474 psp
->pr_size
= btopr(as
->a_resvsize
);
3475 psp
->pr_rssize
= rm_asrss(as
);
3476 psp
->pr_pctmem
= rm_pctmemory(as
);
3478 mutex_enter(&p
->p_lock
);
3481 psp
->pr_bysize
= ptob(psp
->pr_size
);
3482 psp
->pr_byrssize
= ptob(psp
->pr_rssize
);
3486 * Return an array of structures with memory map information.
3487 * We allocate here; the caller must deallocate.
3488 * The caller is also responsible to append the zero-filled entry
3489 * that terminates the PIOCMAP output buffer.
3492 oprgetmap(proc_t
*p
, list_t
*iolhead
)
3494 struct as
*as
= p
->p_as
;
3497 struct seg
*brkseg
, *stkseg
;
3500 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3503 * Request an initial buffer size that doesn't waste memory
3504 * if the address space has only a small number of segments.
3506 pr_iol_initlist(iolhead
, sizeof (*mp
), avl_numnodes(&as
->a_segtree
));
3508 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3511 brkseg
= break_seg(p
);
3512 stkseg
= as_segat(as
, prgetstackbase(p
));
3515 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3516 caddr_t saddr
, naddr
;
3519 if ((seg
->s_flags
& S_HOLE
) != 0) {
3523 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3524 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3528 mp
= pr_iol_newbuf(iolhead
, sizeof (*mp
));
3530 mp
->pr_vaddr
= saddr
;
3531 mp
->pr_size
= naddr
- saddr
;
3532 mp
->pr_off
= segop_getoffset(seg
, saddr
);
3534 if (prot
& PROT_READ
)
3535 mp
->pr_mflags
|= MA_READ
;
3536 if (prot
& PROT_WRITE
)
3537 mp
->pr_mflags
|= MA_WRITE
;
3538 if (prot
& PROT_EXEC
)
3539 mp
->pr_mflags
|= MA_EXEC
;
3540 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3541 mp
->pr_mflags
|= MA_SHARED
;
3543 mp
->pr_mflags
|= MA_BREAK
;
3544 else if (seg
== stkseg
)
3545 mp
->pr_mflags
|= MA_STACK
;
3546 mp
->pr_pagesize
= PAGESIZE
;
3548 ASSERT(tmp
== NULL
);
3549 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3554 #ifdef _SYSCALL32_IMPL
3556 oprgetmap32(proc_t
*p
, list_t
*iolhead
)
3558 struct as
*as
= p
->p_as
;
3561 struct seg
*brkseg
, *stkseg
;
3564 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3567 * Request an initial buffer size that doesn't waste memory
3568 * if the address space has only a small number of segments.
3570 pr_iol_initlist(iolhead
, sizeof (*mp
), avl_numnodes(&as
->a_segtree
));
3572 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3575 brkseg
= break_seg(p
);
3576 stkseg
= as_segat(as
, prgetstackbase(p
));
3579 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3580 caddr_t saddr
, naddr
;
3583 if ((seg
->s_flags
& S_HOLE
) != 0) {
3587 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3588 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3592 mp
= pr_iol_newbuf(iolhead
, sizeof (*mp
));
3594 mp
->pr_vaddr
= (caddr32_t
)(uintptr_t)saddr
;
3595 mp
->pr_size
= (size32_t
)(naddr
- saddr
);
3596 mp
->pr_off
= (off_t
)segop_getoffset(seg
, saddr
);
3598 if (prot
& PROT_READ
)
3599 mp
->pr_mflags
|= MA_READ
;
3600 if (prot
& PROT_WRITE
)
3601 mp
->pr_mflags
|= MA_WRITE
;
3602 if (prot
& PROT_EXEC
)
3603 mp
->pr_mflags
|= MA_EXEC
;
3604 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3605 mp
->pr_mflags
|= MA_SHARED
;
3607 mp
->pr_mflags
|= MA_BREAK
;
3608 else if (seg
== stkseg
)
3609 mp
->pr_mflags
|= MA_STACK
;
3610 mp
->pr_pagesize
= PAGESIZE
;
3612 ASSERT(tmp
== NULL
);
3613 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3617 #endif /* _SYSCALL32_IMPL */
3620 * Return the size of the old /proc page data file.
3623 oprpdsize(struct as
*as
)
3628 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3630 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3633 size
= sizeof (prpageheader_t
);
3635 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3636 caddr_t saddr
, naddr
;
3640 if ((seg
->s_flags
& S_HOLE
) != 0) {
3644 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3645 (void) pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3646 if ((npage
= (naddr
- saddr
) / PAGESIZE
) != 0)
3647 size
+= sizeof (prasmap_t
) + roundlong(npage
);
3649 ASSERT(tmp
== NULL
);
3650 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3655 #ifdef _SYSCALL32_IMPL
3657 oprpdsize32(struct as
*as
)
3662 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3664 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3667 size
= sizeof (ioc_prpageheader32_t
);
3669 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3670 caddr_t saddr
, naddr
;
3674 if ((seg
->s_flags
& S_HOLE
) != 0) {
3678 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3679 (void) pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3680 if ((npage
= (naddr
- saddr
) / PAGESIZE
) != 0)
3681 size
+= sizeof (ioc_prmap32_t
) + round4(npage
);
3683 ASSERT(tmp
== NULL
);
3684 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3688 #endif /* _SYSCALL32_IMPL */
3691 * Read old /proc page data information.
3694 oprpdread(struct as
*as
, uint_t hatid
, struct uio
*uiop
)
3698 prpageheader_t
*php
;
3704 AS_LOCK_ENTER(as
, RW_WRITER
);
3706 if ((seg
= AS_SEGFIRST(as
)) == NULL
) {
3710 size
= oprpdsize(as
);
3711 if (uiop
->uio_resid
< size
) {
3716 buf
= kmem_zalloc(size
, KM_SLEEP
);
3717 php
= (prpageheader_t
*)buf
;
3718 pmp
= (prasmap_t
*)(buf
+ sizeof (prpageheader_t
));
3720 hrt2ts(gethrtime(), &php
->pr_tstamp
);
3724 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3725 caddr_t saddr
, naddr
;
3728 if ((seg
->s_flags
& S_HOLE
) != 0) {
3732 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3738 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3739 if ((len
= naddr
- saddr
) == 0)
3741 npage
= len
/ PAGESIZE
;
3742 next
= (uintptr_t)(pmp
+ 1) + roundlong(npage
);
3744 * It's possible that the address space can change
3745 * subtlely even though we're holding as->a_lock
3746 * due to the nondeterminism of page_exists() in
3747 * the presence of asychronously flushed pages or
3748 * mapped files whose sizes are changing.
3749 * page_exists() may be called indirectly from
3750 * pr_getprot() by a segop_incore() routine.
3751 * If this happens we need to make sure we don't
3752 * overrun the buffer whose size we computed based
3753 * on the initial iteration through the segments.
3754 * Once we've detected an overflow, we need to clean
3755 * up the temporary memory allocated in pr_getprot()
3756 * and retry. If there's a pending signal, we return
3757 * EINTR so that this thread can be dislodged if
3758 * a latent bug causes us to spin indefinitely.
3760 if (next
> (uintptr_t)buf
+ size
) {
3761 pr_getprot_done(&tmp
);
3764 kmem_free(buf
, size
);
3766 if (ISSIG(curthread
, JUSTLOOKING
))
3773 php
->pr_npage
+= npage
;
3774 pmp
->pr_vaddr
= saddr
;
3775 pmp
->pr_npage
= npage
;
3776 pmp
->pr_off
= segop_getoffset(seg
, saddr
);
3778 if (prot
& PROT_READ
)
3779 pmp
->pr_mflags
|= MA_READ
;
3780 if (prot
& PROT_WRITE
)
3781 pmp
->pr_mflags
|= MA_WRITE
;
3782 if (prot
& PROT_EXEC
)
3783 pmp
->pr_mflags
|= MA_EXEC
;
3784 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3785 pmp
->pr_mflags
|= MA_SHARED
;
3786 pmp
->pr_pagesize
= PAGESIZE
;
3787 hat_getstat(as
, saddr
, len
, hatid
,
3788 (char *)(pmp
+ 1), HAT_SYNC_ZERORM
);
3789 pmp
= (prasmap_t
*)next
;
3791 ASSERT(tmp
== NULL
);
3792 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3796 ASSERT((uintptr_t)pmp
<= (uintptr_t)buf
+ size
);
3797 error
= uiomove(buf
, (caddr_t
)pmp
- buf
, UIO_READ
, uiop
);
3798 kmem_free(buf
, size
);
3803 #ifdef _SYSCALL32_IMPL
3805 oprpdread32(struct as
*as
, uint_t hatid
, struct uio
*uiop
)
3809 ioc_prpageheader32_t
*php
;
3810 ioc_prasmap32_t
*pmp
;
3815 AS_LOCK_ENTER(as
, RW_WRITER
);
3817 if ((seg
= AS_SEGFIRST(as
)) == NULL
) {
3821 size
= oprpdsize32(as
);
3822 if (uiop
->uio_resid
< size
) {
3827 buf
= kmem_zalloc(size
, KM_SLEEP
);
3828 php
= (ioc_prpageheader32_t
*)buf
;
3829 pmp
= (ioc_prasmap32_t
*)(buf
+ sizeof (ioc_prpageheader32_t
));
3831 hrt2ts32(gethrtime(), &php
->pr_tstamp
);
3835 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3836 caddr_t saddr
, naddr
;
3839 if ((seg
->s_flags
& S_HOLE
) != 0) {
3843 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3849 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3850 if ((len
= naddr
- saddr
) == 0)
3852 npage
= len
/ PAGESIZE
;
3853 next
= (uintptr_t)(pmp
+ 1) + round4(npage
);
3855 * It's possible that the address space can change
3856 * subtlely even though we're holding as->a_lock
3857 * due to the nondeterminism of page_exists() in
3858 * the presence of asychronously flushed pages or
3859 * mapped files whose sizes are changing.
3860 * page_exists() may be called indirectly from
3861 * pr_getprot() by a segop_incore() routine.
3862 * If this happens we need to make sure we don't
3863 * overrun the buffer whose size we computed based
3864 * on the initial iteration through the segments.
3865 * Once we've detected an overflow, we need to clean
3866 * up the temporary memory allocated in pr_getprot()
3867 * and retry. If there's a pending signal, we return
3868 * EINTR so that this thread can be dislodged if
3869 * a latent bug causes us to spin indefinitely.
3871 if (next
> (uintptr_t)buf
+ size
) {
3872 pr_getprot_done(&tmp
);
3875 kmem_free(buf
, size
);
3877 if (ISSIG(curthread
, JUSTLOOKING
))
3884 php
->pr_npage
+= npage
;
3885 pmp
->pr_vaddr
= (uint32_t)(uintptr_t)saddr
;
3886 pmp
->pr_npage
= (uint32_t)npage
;
3887 pmp
->pr_off
= (int32_t)segop_getoffset(seg
, saddr
);
3889 if (prot
& PROT_READ
)
3890 pmp
->pr_mflags
|= MA_READ
;
3891 if (prot
& PROT_WRITE
)
3892 pmp
->pr_mflags
|= MA_WRITE
;
3893 if (prot
& PROT_EXEC
)
3894 pmp
->pr_mflags
|= MA_EXEC
;
3895 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3896 pmp
->pr_mflags
|= MA_SHARED
;
3897 pmp
->pr_pagesize
= PAGESIZE
;
3898 hat_getstat(as
, saddr
, len
, hatid
,
3899 (char *)(pmp
+ 1), HAT_SYNC_ZERORM
);
3900 pmp
= (ioc_prasmap32_t
*)next
;
3902 ASSERT(tmp
== NULL
);
3903 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3907 ASSERT((uintptr_t)pmp
== (uintptr_t)buf
+ size
);
3908 error
= uiomove(buf
, (caddr_t
)pmp
- buf
, UIO_READ
, uiop
);
3909 kmem_free(buf
, size
);
3913 #endif /* _SYSCALL32_IMPL */
3916 #ifdef _SYSCALL32_IMPL
3925 caller_context_t
*ct
)
3927 switch (curproc
->p_model
) {
3928 case DATAMODEL_ILP32
:
3929 return (prioctl32(vp
, cmd
, arg
, flag
, cr
, rvalp
, ct
));
3930 case DATAMODEL_LP64
:
3931 return (prioctl64(vp
, cmd
, arg
, flag
, cr
, rvalp
, ct
));
3936 #endif /* _SYSCALL32_IMPL */