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.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All rights reserved. */
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/vmparam.h>
34 #include <sys/cmn_err.h>
36 #include <sys/debug.h>
37 #include <sys/errno.h>
39 #include <sys/inline.h>
42 #include <sys/brand.h>
43 #include <sys/sysmacros.h>
44 #include <sys/systm.h>
46 #include <sys/vnode.h>
47 #include <sys/cpuvar.h>
48 #include <sys/session.h>
49 #include <sys/signal.h>
53 #include <sys/class.h>
56 #include <sys/fault.h>
57 #include <sys/syscall.h>
58 #include <sys/schedctl.h>
60 #include <sys/old_procfs.h>
63 #include <sys/msacct.h>
68 #include <vm/seg_vn.h>
69 #include <sys/contract_impl.h>
70 #include <sys/ctfs_impl.h>
73 #if defined(__i386) || defined(__i386_COMPAT)
74 #include <sys/sysi86.h>
77 #include <sys/proc/prdata.h>
79 static int isprwrioctl(int);
80 static ulong_t
prmaprunflags(long);
81 static long prmapsetflags(long);
82 static void prsetrun(kthread_t
*, prrun_t
*);
83 static int propenm(prnode_t
*, caddr_t
, caddr_t
, int *, cred_t
*);
84 extern void oprgetstatus(kthread_t
*, prstatus_t
*, zone_t
*);
85 extern void oprgetpsinfo(proc_t
*, prpsinfo_t
*, kthread_t
*);
86 static int oprgetmap(proc_t
*, list_t
*);
89 prctioctl(prnode_t
*pnp
, int cmd
, intptr_t arg
, int flag
, cred_t
*cr
)
93 ct_param_t
*param
= &kparam
.param
;
96 if (cmd
!= CT_TSET
&& cmd
!= CT_TGET
)
99 error
= ctparam_copyin((void *)arg
, &kparam
, flag
, cmd
);
103 if ((error
= prlock(pnp
, ZNO
)) != 0) {
104 kmem_free(kparam
.ctpm_kbuf
, param
->ctpm_size
);
108 tmpl
= pnp
->pr_common
->prc_thread
->t_lwp
->lwp_ct_active
[pnp
->pr_cttype
];
111 kmem_free(kparam
.ctpm_kbuf
, param
->ctpm_size
);
116 error
= ctmpl_set(tmpl
, &kparam
, cr
);
118 error
= ctmpl_get(tmpl
, &kparam
);
122 if (cmd
== CT_TGET
&& error
== 0) {
123 error
= ctparam_copyout(&kparam
, (void *)arg
, flag
);
125 kmem_free(kparam
.ctpm_kbuf
, param
->ctpm_size
);
133 * Control operations (lots).
135 /* ARGSUSED */ /* BEGIN CSTYLED */
136 #ifdef _SYSCALL32_IMPL
145 caller_context_t
*ct
)
155 caller_context_t
*ct
)
156 #endif /* _SYSCALL32_IMPL */ /* END CSTYLED */
158 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
159 caddr_t cmaddr
= (caddr_t
)arg
;
164 prnode_t
*pnp
= VTOP(vp
);
166 prnode_t
*xpnp
= NULL
;
170 size_t thingsize
= 0;
173 * For copyin()/copyout().
194 auxv_t auxv
[__KERN_NAUXV_IMPL
];
197 if (pnp
->pr_type
== PR_TMPL
)
198 return (prctioctl(pnp
, cmd
, arg
, flag
, cr
));
201 * Support for old /proc interface.
203 if (pnp
->pr_pidfile
!= NULL
) {
204 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
205 vp
= pnp
->pr_pidfile
;
207 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
210 if (pnp
->pr_type
!= PR_PIDFILE
&& pnp
->pr_type
!= PR_LWPIDFILE
)
214 * Fail ioctls which are logically "write" requests unless
215 * the user has write permission.
217 if ((flag
& FWRITE
) == 0 && isprwrioctl(cmd
))
221 * Perform any necessary copyin() operations before
222 * locking the process. Helps avoid deadlocks and
223 * improves performance.
225 * Also, detect invalid ioctl codes here to avoid
226 * locking a process unnnecessarily.
228 * Also, prepare to allocate space that will be needed below,
234 thingsize
= sizeof (proc_t
);
237 thingsize
= sizeof (user_t
);
257 case PIOCSXREG
: /* set extra registers */
258 case PIOCGXREG
: /* get extra registers */
262 thingsize
= (nsig
-1) * sizeof (struct sigaction
);
276 * We will need this below.
277 * Allocate it now, before locking the process.
279 xpnp
= prgetnode(vp
, PR_OPAGEDATA
);
285 #if defined(__i386) || defined(__amd64)
289 #endif /* __i386 || __amd64 */
292 case PIOCOPENM
: /* open mapped object for reading */
295 else if (copyin(cmaddr
, &un
.va
, sizeof (un
.va
)))
299 case PIOCRUN
: /* make lwp or process runnable */
301 un
.prrun
.pr_flags
= 0;
302 else if (copyin(cmaddr
, &un
.prrun
, sizeof (un
.prrun
)))
306 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
307 if (copyin(cmaddr
, &un
.lwpid
, sizeof (un
.lwpid
)))
311 case PIOCSTRACE
: /* set signal trace mask */
312 if (copyin(cmaddr
, &un
.smask
, sizeof (un
.smask
)))
316 case PIOCSSIG
: /* set current signal */
318 un
.info
.si_signo
= 0;
319 else if (copyin(cmaddr
, &un
.info
, sizeof (un
.info
)))
323 case PIOCKILL
: /* send signal */
324 case PIOCUNKILL
: /* delete a signal */
325 if (copyin(cmaddr
, &un
.signo
, sizeof (un
.signo
)))
329 case PIOCNICE
: /* set nice priority */
330 if (copyin(cmaddr
, &un
.nice
, sizeof (un
.nice
)))
334 case PIOCSENTRY
: /* set syscall entry bit mask */
335 case PIOCSEXIT
: /* set syscall exit bit mask */
336 if (copyin(cmaddr
, &un
.prmask
, sizeof (un
.prmask
)))
340 case PIOCSET
: /* set process flags */
341 case PIOCRESET
: /* reset process flags */
342 if (copyin(cmaddr
, &un
.flags
, sizeof (un
.flags
)))
346 case PIOCSREG
: /* set general registers */
347 if (copyin(cmaddr
, un
.regs
, sizeof (un
.regs
)))
351 case PIOCSFPREG
: /* set floating-point registers */
352 if (copyin(cmaddr
, &un
.fpregs
, sizeof (un
.fpregs
)))
356 case PIOCSHOLD
: /* set signal-hold mask */
357 if (copyin(cmaddr
, &un
.holdmask
, sizeof (un
.holdmask
)))
361 case PIOCSFAULT
: /* set mask of traced faults */
362 if (copyin(cmaddr
, &un
.fltmask
, sizeof (un
.fltmask
)))
376 * If we need kmem_alloc()d space then we allocate it now, before
377 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
378 * holding the process lock leads to deadlock with the clock thread.
379 * (The clock thread wakes up the pageout daemon to free up space.
380 * If the clock thread blocks behind us and we are sleeping waiting
381 * for space, then space may never become available.)
384 ASSERT(thing
== NULL
);
385 thing
= kmem_alloc(thingsize
, KM_SLEEP
);
395 case PIOCSXREG
: /* set extra registers */
397 * perform copyin before grabbing the process lock
400 if (copyin(cmaddr
, thing
, thingsize
)) {
401 kmem_free(thing
, thingsize
);
405 /* fall through... */
411 if ((error
= prlock(pnp
, zdisp
)) != 0) {
413 kmem_free(thing
, thingsize
);
419 pcp
= pnp
->pr_common
;
424 * Choose a thread/lwp for the operation.
426 if (zdisp
== ZNO
&& cmd
!= PIOCSTOP
&& cmd
!= PIOCWSTOP
) {
427 if (pnp
->pr_type
== PR_LWPIDFILE
&& cmd
!= PIOCLSTATUS
) {
431 t
= prchoose(p
); /* returns locked thread */
441 case PIOCGETPR
: /* read struct proc */
447 if (copyout(prp
, cmaddr
, sizeof (proc_t
)))
449 kmem_free(prp
, sizeof (proc_t
));
454 case PIOCGETU
: /* read u-area */
456 user_t
*userp
= thing
;
461 if (copyout(userp
, cmaddr
, sizeof (user_t
)))
463 kmem_free(userp
, sizeof (user_t
));
468 case PIOCOPENM
: /* open mapped object for reading */
469 error
= propenm(pnp
, cmaddr
, un
.va
, rvalp
, cr
);
470 /* propenm() called prunlock(pnp) */
473 case PIOCSTOP
: /* stop process or lwp from running */
474 case PIOCWSTOP
: /* wait for process or lwp to stop */
476 * Can't apply to a system process.
478 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
488 * If an lwp is waiting for itself or its process, don't wait.
489 * The stopped lwp would never see the fact that it is stopped.
491 if ((pnp
->pr_type
== PR_LWPIDFILE
)?
492 (pcp
->prc_thread
== curthread
) : (p
== curproc
)) {
493 if (cmd
== PIOCWSTOP
)
499 if ((error
= pr_wait_stop(pnp
, (time_t)0)) != 0)
500 break; /* pr_wait_stop() unlocked the process */
506 * Return process/lwp status information.
508 t
= pr_thread(pnp
); /* returns locked thread */
510 oprgetstatus(t
, &un
.prstat
, VTOZONE(vp
));
512 if (copyout(&un
.prstat
, cmaddr
, sizeof (un
.prstat
)))
517 case PIOCRUN
: /* make lwp or process runnable */
519 long flags
= un
.prrun
.pr_flags
;
522 * Cannot set an lwp running is it is not stopped.
523 * Also, no lwp other than the /proc agent lwp can
524 * be set running so long as the /proc agent lwp exists.
526 if ((!ISTOPPED(t
) && !VSTOPPED(t
) &&
527 !(t
->t_proc_flag
& TP_PRSTOP
)) ||
528 (p
->p_agenttp
!= NULL
&&
529 (t
!= p
->p_agenttp
|| pnp
->pr_type
!= PR_LWPIDFILE
))) {
535 if (flags
& (PRSHOLD
|PRSTRACE
|PRSFAULT
|PRSVADDR
))
536 prsetrun(t
, &un
.prrun
);
538 error
= pr_setrun(pnp
, prmaprunflags(flags
));
544 case PIOCLWPIDS
: /* get array of lwp identifiers */
551 Nlwp
= nlwp
= p
->p_lwpcnt
;
553 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (id_t
)) {
554 kmem_free(thing
, thingsize
);
558 thingsize
= (Nlwp
+1) * sizeof (id_t
);
559 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
569 if ((t
= p
->p_tlist
) != NULL
) {
571 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
575 } while ((t
= t
->t_forw
) != p
->p_tlist
);
580 if (copyout(Bidp
, cmaddr
, (Nlwp
+1) * sizeof (id_t
)))
582 kmem_free(Bidp
, (Nlwp
+1) * sizeof (id_t
));
586 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
592 if ((xvp
= prlwpnode(pnp
, un
.lwpid
)) == NULL
)
594 else if (error
= fassign(&xvp
, flag
& (FREAD
|FWRITE
), &n
)) {
601 case PIOCOPENPD
: /* return /proc page data file descriptor */
603 vnode_t
*xvp
= PTOV(xpnp
);
604 vnode_t
*dp
= pnp
->pr_parent
;
607 if (pnp
->pr_type
== PR_LWPIDFILE
) {
608 dp
= VTOP(dp
)->pr_parent
;
609 dp
= VTOP(dp
)->pr_parent
;
611 ASSERT(VTOP(dp
)->pr_type
== PR_PIDDIR
);
614 pcp
= pnp
->pr_pcommon
;
615 xpnp
->pr_ino
= ptoi(pcp
->prc_pid
);
616 xpnp
->pr_common
= pcp
;
617 xpnp
->pr_pcommon
= pcp
;
618 xpnp
->pr_parent
= dp
;
620 xpnp
->pr_next
= p
->p_plist
;
624 if (error
= fassign(&xvp
, FREAD
, &n
)) {
633 case PIOCGTRACE
: /* get signal trace mask */
634 prassignset(&un
.smask
, &p
->p_sigmask
);
636 if (copyout(&un
.smask
, cmaddr
, sizeof (un
.smask
)))
640 case PIOCSTRACE
: /* set signal trace mask */
641 prdelset(&un
.smask
, SIGKILL
);
642 prassignset(&p
->p_sigmask
, &un
.smask
);
643 if (!sigisempty(&p
->p_sigmask
))
644 p
->p_proc_flag
|= P_PR_TRACE
;
645 else if (prisempty(&p
->p_fltmask
)) {
647 if (up
->u_systrap
== 0)
648 p
->p_proc_flag
&= ~P_PR_TRACE
;
653 case PIOCSSIG
: /* set current signal */
654 error
= pr_setsig(pnp
, &un
.info
);
656 if (un
.info
.si_signo
== SIGKILL
&& error
== 0)
660 case PIOCKILL
: /* send signal */
662 int sig
= (int)un
.signo
;
664 error
= pr_kill(pnp
, sig
, cr
);
666 if (sig
== SIGKILL
&& error
== 0)
671 case PIOCUNKILL
: /* delete a signal */
672 error
= pr_unkill(pnp
, (int)un
.signo
);
676 case PIOCNICE
: /* set nice priority */
677 error
= pr_nice(p
, (int)un
.nice
, cr
);
681 case PIOCGENTRY
: /* get syscall entry bit mask */
682 case PIOCGEXIT
: /* get syscall exit bit mask */
684 if (cmd
== PIOCGENTRY
) {
685 prassignset(&un
.prmask
, &up
->u_entrymask
);
687 prassignset(&un
.prmask
, &up
->u_exitmask
);
690 if (copyout(&un
.prmask
, cmaddr
, sizeof (un
.prmask
)))
694 case PIOCSENTRY
: /* set syscall entry bit mask */
695 case PIOCSEXIT
: /* set syscall exit bit mask */
696 pr_setentryexit(p
, &un
.prmask
, cmd
== PIOCSENTRY
);
700 case PIOCSRLC
: /* obsolete: set running on last /proc close */
701 error
= pr_set(p
, prmapsetflags(PR_RLC
));
705 case PIOCRRLC
: /* obsolete: reset run-on-last-close flag */
706 error
= pr_unset(p
, prmapsetflags(PR_RLC
));
710 case PIOCSFORK
: /* obsolete: set inherit-on-fork flag */
711 error
= pr_set(p
, prmapsetflags(PR_FORK
));
715 case PIOCRFORK
: /* obsolete: reset inherit-on-fork flag */
716 error
= pr_unset(p
, prmapsetflags(PR_FORK
));
720 case PIOCSET
: /* set process flags */
721 error
= pr_set(p
, prmapsetflags(un
.flags
));
725 case PIOCRESET
: /* reset process flags */
726 error
= pr_unset(p
, prmapsetflags(un
.flags
));
730 case PIOCGREG
: /* get general registers */
731 if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
732 bzero(un
.regs
, sizeof (un
.regs
));
734 /* drop p_lock while touching the lwp's stack */
735 mutex_exit(&p
->p_lock
);
736 prgetprregs(lwp
, un
.regs
);
737 mutex_enter(&p
->p_lock
);
740 if (copyout(un
.regs
, cmaddr
, sizeof (un
.regs
)))
744 case PIOCSREG
: /* set general registers */
745 if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
748 /* drop p_lock while touching the lwp's stack */
749 mutex_exit(&p
->p_lock
);
750 prsetprregs(lwp
, un
.regs
, 0);
751 mutex_enter(&p
->p_lock
);
756 case PIOCGFPREG
: /* get floating-point registers */
759 error
= EINVAL
; /* No FP support */
763 if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
764 bzero(&un
.fpregs
, sizeof (un
.fpregs
));
766 /* drop p_lock while touching the lwp's stack */
767 mutex_exit(&p
->p_lock
);
768 prgetprfpregs(lwp
, &un
.fpregs
);
769 mutex_enter(&p
->p_lock
);
772 if (copyout(&un
.fpregs
, cmaddr
, sizeof (un
.fpregs
)))
776 case PIOCSFPREG
: /* set floating-point registers */
778 error
= EINVAL
; /* No FP support */
779 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
782 /* drop p_lock while touching the lwp's stack */
783 mutex_exit(&p
->p_lock
);
784 prsetprfpregs(lwp
, &un
.fpregs
);
785 mutex_enter(&p
->p_lock
);
790 case PIOCGXREGSIZE
: /* get the size of the extra registers */
795 xregsize
= prgetprxregsize(p
);
797 if (copyout(&xregsize
, cmaddr
, sizeof (xregsize
)))
801 error
= EINVAL
; /* No extra register support */
806 case PIOCGXREG
: /* get extra registers */
808 bzero(thing
, thingsize
);
809 if (t
->t_state
== TS_STOPPED
|| VSTOPPED(t
)) {
810 /* drop p_lock to touch the stack */
811 mutex_exit(&p
->p_lock
);
812 prgetprxregs(lwp
, thing
);
813 mutex_enter(&p
->p_lock
);
816 if (copyout(thing
, cmaddr
, thingsize
))
820 error
= EINVAL
; /* No extra register support */
823 kmem_free(thing
, thingsize
);
828 case PIOCSXREG
: /* set extra registers */
829 if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
832 error
= EINVAL
; /* No extra register support */
834 /* drop p_lock while touching the lwp's stack */
835 mutex_exit(&p
->p_lock
);
836 prsetprxregs(lwp
, thing
);
837 mutex_enter(&p
->p_lock
);
841 kmem_free(thing
, thingsize
);
846 case PIOCSTATUS
: /* get process/lwp status */
847 oprgetstatus(t
, &un
.prstat
, VTOZONE(vp
));
849 if (copyout(&un
.prstat
, cmaddr
, sizeof (un
.prstat
)))
853 case PIOCLSTATUS
: /* get status for process & all lwps */
860 nlwp
= Nlwp
= p
->p_lwpcnt
;
862 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (prstatus_t
)) {
863 kmem_free(thing
, thingsize
);
867 thingsize
= (Nlwp
+1) * sizeof (prstatus_t
);
868 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
878 oprgetstatus(t
, prsp
, VTOZONE(vp
));
881 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
884 oprgetstatus(t
, ++prsp
, VTOZONE(vp
));
885 } while ((t
= t
->t_forw
) != p
->p_tlist
);
888 if (copyout(Bprsp
, cmaddr
, (Nlwp
+1) * sizeof (prstatus_t
)))
891 kmem_free(Bprsp
, (Nlwp
+1) * sizeof (prstatus_t
));
895 case PIOCPSINFO
: /* get ps(1) information */
897 prpsinfo_t
*psp
= &un
.prps
;
900 (pnp
->pr_type
== PR_LWPIDFILE
)? pcp
->prc_thread
: NULL
);
903 if (copyout(&un
.prps
, cmaddr
, sizeof (un
.prps
)))
908 case PIOCMAXSIG
: /* get maximum signal number */
913 if (copyout(&n
, cmaddr
, sizeof (n
)))
918 case PIOCACTION
: /* get signal action structures */
921 struct sigaction
*sap
= thing
;
924 for (sig
= 1; sig
< nsig
; sig
++)
925 prgetaction(p
, up
, sig
, &sap
[sig
-1]);
927 if (copyout(sap
, cmaddr
, (nsig
-1) * sizeof (struct sigaction
)))
929 kmem_free(sap
, (nsig
-1) * sizeof (struct sigaction
));
934 case PIOCGHOLD
: /* get signal-hold mask */
935 schedctl_finish_sigblock(t
);
936 sigktou(&t
->t_hold
, &un
.holdmask
);
938 if (copyout(&un
.holdmask
, cmaddr
, sizeof (un
.holdmask
)))
942 case PIOCSHOLD
: /* set signal-hold mask */
943 pr_sethold(pnp
, &un
.holdmask
);
947 case PIOCNMAP
: /* get number of memory mappings */
950 struct as
*as
= p
->p_as
;
952 if ((p
->p_flag
& SSYS
) || as
== &kas
)
955 mutex_exit(&p
->p_lock
);
956 AS_LOCK_ENTER(as
, RW_WRITER
);
959 mutex_enter(&p
->p_lock
);
962 if (copyout(&n
, cmaddr
, sizeof (int)))
967 case PIOCMAP
: /* get memory map information */
970 struct as
*as
= p
->p_as
;
972 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
976 mutex_exit(&p
->p_lock
);
977 AS_LOCK_ENTER(as
, RW_WRITER
);
978 error
= oprgetmap(p
, &iolhead
);
980 mutex_enter(&p
->p_lock
);
983 error
= pr_iol_copyout_and_free(&iolhead
,
987 * The procfs PIOCMAP ioctl returns an all-zero buffer
988 * to indicate the end of the prmap[] array.
989 * Append it to whatever has already been copied out.
991 bzero(&un
.prmap
, sizeof (un
.prmap
));
992 if (!error
&& copyout(&un
.prmap
, cmaddr
, sizeof (un
.prmap
)))
998 case PIOCGFAULT
: /* get mask of traced faults */
999 prassignset(&un
.fltmask
, &p
->p_fltmask
);
1001 if (copyout(&un
.fltmask
, cmaddr
, sizeof (un
.fltmask
)))
1005 case PIOCSFAULT
: /* set mask of traced faults */
1006 pr_setfault(p
, &un
.fltmask
);
1010 case PIOCCFAULT
: /* clear current fault */
1011 lwp
->lwp_curflt
= 0;
1015 case PIOCCRED
: /* get process credentials */
1019 mutex_enter(&p
->p_crlock
);
1021 un
.prcred
.pr_euid
= crgetuid(cp
);
1022 un
.prcred
.pr_ruid
= crgetruid(cp
);
1023 un
.prcred
.pr_suid
= crgetsuid(cp
);
1024 un
.prcred
.pr_egid
= crgetgid(cp
);
1025 un
.prcred
.pr_rgid
= crgetrgid(cp
);
1026 un
.prcred
.pr_sgid
= crgetsgid(cp
);
1027 un
.prcred
.pr_ngroups
= crgetngroups(cp
);
1028 mutex_exit(&p
->p_crlock
);
1031 if (copyout(&un
.prcred
, cmaddr
, sizeof (un
.prcred
)))
1036 case PIOCGROUPS
: /* get supplementary groups */
1040 mutex_enter(&p
->p_crlock
);
1043 mutex_exit(&p
->p_crlock
);
1046 if (copyout(crgetgroups(cp
), cmaddr
,
1047 MAX(crgetngroups(cp
), 1) * sizeof (gid_t
)))
1053 case PIOCUSAGE
: /* get usage info */
1056 * For an lwp file descriptor, return just the lwp usage.
1057 * For a process file descriptor, return total usage,
1058 * all current lwps plus all defunct lwps.
1060 prhusage_t
*pup
= &un
.prhusage
;
1063 bzero(pup
, sizeof (*pup
));
1064 pup
->pr_tstamp
= gethrtime();
1066 if (pnp
->pr_type
== PR_LWPIDFILE
) {
1067 t
= pcp
->prc_thread
;
1073 pup
->pr_count
= p
->p_defunct
;
1074 pup
->pr_create
= p
->p_mstart
;
1075 pup
->pr_term
= p
->p_mterm
;
1077 pup
->pr_rtime
= p
->p_mlreal
;
1078 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1079 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1080 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1081 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1082 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1083 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1084 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1085 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1086 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1087 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1089 pup
->pr_minf
= p
->p_ru
.minflt
;
1090 pup
->pr_majf
= p
->p_ru
.majflt
;
1091 pup
->pr_nswap
= p
->p_ru
.nswap
;
1092 pup
->pr_inblk
= p
->p_ru
.inblock
;
1093 pup
->pr_oublk
= p
->p_ru
.oublock
;
1094 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1095 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1096 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1097 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1098 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1099 pup
->pr_sysc
= p
->p_ru
.sysc
;
1100 pup
->pr_ioch
= p
->p_ru
.ioch
;
1103 * Add the usage information for each active lwp.
1105 if ((t
= p
->p_tlist
) != NULL
&&
1106 !(pcp
->prc_flags
& PRC_DESTROY
)) {
1108 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
1111 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1117 upup
= kmem_zalloc(sizeof (*upup
), KM_SLEEP
);
1118 prcvtusage(&un
.prhusage
, upup
);
1119 if (copyout(upup
, cmaddr
, sizeof (*upup
)))
1121 kmem_free(upup
, sizeof (*upup
));
1126 case PIOCLUSAGE
: /* get detailed usage info */
1135 nlwp
= Nlwp
= (pcp
->prc_flags
& PRC_DESTROY
)? 0 : p
->p_lwpcnt
;
1137 if (thing
&& thingsize
!=
1138 sizeof (prhusage_t
) + (Nlwp
+1) * sizeof (prusage_t
)) {
1139 kmem_free(thing
, thingsize
);
1142 if (thing
== NULL
) {
1143 thingsize
= sizeof (prhusage_t
) +
1144 (Nlwp
+1) * sizeof (prusage_t
);
1145 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
1147 if (thing
== NULL
) {
1153 upup
= Bupup
= (prusage_t
*)(pup
+ 1);
1155 ASSERT(p
== pcp
->prc_proc
);
1157 curtime
= gethrtime();
1160 * First the summation over defunct lwps.
1162 bzero(pup
, sizeof (*pup
));
1163 pup
->pr_count
= p
->p_defunct
;
1164 pup
->pr_tstamp
= curtime
;
1165 pup
->pr_create
= p
->p_mstart
;
1166 pup
->pr_term
= p
->p_mterm
;
1168 pup
->pr_rtime
= p
->p_mlreal
;
1169 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
1170 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
1171 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
1172 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
1173 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
1174 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
1175 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
1176 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
1177 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
1178 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
1180 pup
->pr_minf
= p
->p_ru
.minflt
;
1181 pup
->pr_majf
= p
->p_ru
.majflt
;
1182 pup
->pr_nswap
= p
->p_ru
.nswap
;
1183 pup
->pr_inblk
= p
->p_ru
.inblock
;
1184 pup
->pr_oublk
= p
->p_ru
.oublock
;
1185 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
1186 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
1187 pup
->pr_sigs
= p
->p_ru
.nsignals
;
1188 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
1189 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
1190 pup
->pr_sysc
= p
->p_ru
.sysc
;
1191 pup
->pr_ioch
= p
->p_ru
.ioch
;
1193 prcvtusage(pup
, upup
);
1196 * Fill one prusage struct for each active lwp.
1198 if ((t
= p
->p_tlist
) != NULL
&&
1199 !(pcp
->prc_flags
& PRC_DESTROY
)) {
1201 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
1206 prcvtusage(pup
, upup
);
1207 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1212 if (copyout(Bupup
, cmaddr
, (Nlwp
+1) * sizeof (prusage_t
)))
1214 kmem_free(thing
, thingsize
);
1219 case PIOCNAUXV
: /* get number of aux vector entries */
1221 int n
= __KERN_NAUXV_IMPL
;
1224 if (copyout(&n
, cmaddr
, sizeof (int)))
1229 case PIOCAUXV
: /* get aux vector (see sys/auxv.h) */
1232 bcopy(up
->u_auxv
, un
.auxv
,
1233 __KERN_NAUXV_IMPL
* sizeof (auxv_t
));
1235 if (copyout(un
.auxv
, cmaddr
,
1236 __KERN_NAUXV_IMPL
* sizeof (auxv_t
)))
1241 #if defined(__i386) || defined(__amd64)
1242 case PIOCNLDT
: /* get number of LDT entries */
1246 mutex_exit(&p
->p_lock
);
1247 mutex_enter(&p
->p_ldtlock
);
1249 mutex_exit(&p
->p_ldtlock
);
1250 mutex_enter(&p
->p_lock
);
1252 if (copyout(&n
, cmaddr
, sizeof (n
)))
1257 case PIOCLDT
: /* get LDT entries */
1262 mutex_exit(&p
->p_lock
);
1263 mutex_enter(&p
->p_ldtlock
);
1266 if (thing
&& thingsize
!= (n
+1) * sizeof (*ssd
)) {
1267 kmem_free(thing
, thingsize
);
1270 if (thing
== NULL
) {
1271 thingsize
= (n
+1) * sizeof (*ssd
);
1272 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
1274 if (thing
== NULL
) {
1275 mutex_exit(&p
->p_ldtlock
);
1276 mutex_enter(&p
->p_lock
);
1285 mutex_exit(&p
->p_ldtlock
);
1286 mutex_enter(&p
->p_lock
);
1289 /* mark the end of the list with a null entry */
1290 bzero(&ssd
[n
], sizeof (*ssd
));
1291 if (copyout(ssd
, cmaddr
, (n
+1) * sizeof (*ssd
)))
1293 kmem_free(ssd
, (n
+1) * sizeof (*ssd
));
1296 #endif /* __i386 || __amd64 */
1306 ASSERT(thing
== NULL
);
1307 ASSERT(xpnp
== NULL
);
1311 #ifdef _SYSCALL32_IMPL
1313 static int oprgetmap32(proc_t
*, list_t
*);
1316 oprgetstatus32(kthread_t
*t
, prstatus32_t
*sp
, zone_t
*zp
)
1318 proc_t
*p
= ttoproc(t
);
1319 klwp_t
*lwp
= ttolwp(t
);
1324 ASSERT(MUTEX_HELD(&p
->p_lock
));
1327 bzero(sp
, sizeof (*sp
));
1329 if (t
->t_state
== TS_STOPPED
) {
1330 flags
|= PR_STOPPED
;
1331 if ((t
->t_schedflag
& TS_PSTART
) == 0)
1333 } else if (VSTOPPED(t
)) {
1334 flags
|= PR_STOPPED
|PR_ISTOP
;
1336 if (!(flags
& PR_ISTOP
) && (t
->t_proc_flag
& TP_PRSTOP
))
1338 if (lwp
->lwp_asleep
)
1340 if (p
->p_proc_flag
& P_PR_FORK
)
1342 if (p
->p_proc_flag
& P_PR_RUNLCL
)
1344 if (p
->p_proc_flag
& P_PR_KILLCL
)
1346 if (p
->p_proc_flag
& P_PR_ASYNC
)
1348 if (p
->p_proc_flag
& P_PR_BPTADJ
)
1350 if (p
->p_proc_flag
& P_PR_PTRACE
)
1351 flags
|= PR_PCOMPAT
;
1352 if (t
->t_proc_flag
& TP_MSACCT
)
1354 sp
->pr_flags
= flags
;
1356 sp
->pr_why
= PR_REQUESTED
;
1359 sp
->pr_why
= t
->t_whystop
;
1360 sp
->pr_what
= t
->t_whatstop
;
1363 if (t
->t_whystop
== PR_FAULTED
) {
1364 siginfo_kto32(&lwp
->lwp_siginfo
, &sp
->pr_info
);
1365 if (t
->t_whatstop
== FLTPAGE
)
1366 sp
->pr_info
.si_addr
=
1367 (caddr32_t
)(uintptr_t)lwp
->lwp_siginfo
.si_addr
;
1368 } else if (lwp
->lwp_curinfo
)
1369 siginfo_kto32(&lwp
->lwp_curinfo
->sq_info
, &sp
->pr_info
);
1371 if (SI_FROMUSER(&lwp
->lwp_siginfo
) && zp
->zone_id
!= GLOBAL_ZONEID
&&
1372 sp
->pr_info
.si_zoneid
!= zp
->zone_id
) {
1373 sp
->pr_info
.si_pid
= zp
->zone_zsched
->p_pid
;
1374 sp
->pr_info
.si_uid
= 0;
1375 sp
->pr_info
.si_ctid
= -1;
1376 sp
->pr_info
.si_zoneid
= zp
->zone_id
;
1379 sp
->pr_cursig
= lwp
->lwp_cursig
;
1380 prassignset(&sp
->pr_sigpend
, &p
->p_sig
);
1381 prassignset(&sp
->pr_lwppend
, &t
->t_sig
);
1382 schedctl_finish_sigblock(t
);
1383 prassignset(&sp
->pr_sighold
, &t
->t_hold
);
1384 sp
->pr_altstack
.ss_sp
=
1385 (caddr32_t
)(uintptr_t)lwp
->lwp_sigaltstack
.ss_sp
;
1386 sp
->pr_altstack
.ss_size
= (size32_t
)lwp
->lwp_sigaltstack
.ss_size
;
1387 sp
->pr_altstack
.ss_flags
= (int32_t)lwp
->lwp_sigaltstack
.ss_flags
;
1388 prgetaction32(p
, up
, lwp
->lwp_cursig
, &sp
->pr_action
);
1389 sp
->pr_pid
= p
->p_pid
;
1390 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
1391 (p
->p_flag
& SZONETOP
)) {
1392 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
1394 * Inside local zones, fake zsched's pid as parent pids for
1395 * processes which reference processes outside of the zone.
1397 sp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
1399 sp
->pr_ppid
= p
->p_ppid
;
1401 sp
->pr_pgrp
= p
->p_pgrp
;
1402 sp
->pr_sid
= p
->p_sessp
->s_sid
;
1403 hrt2ts32(mstate_aggr_state(p
, LMS_USER
), &sp
->pr_utime
);
1404 hrt2ts32(mstate_aggr_state(p
, LMS_SYSTEM
), &sp
->pr_stime
);
1405 TICK_TO_TIMESTRUC32(p
->p_cutime
, &sp
->pr_cutime
);
1406 TICK_TO_TIMESTRUC32(p
->p_cstime
, &sp
->pr_cstime
);
1407 (void) strncpy(sp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
1408 sizeof (sp
->pr_clname
) - 1);
1409 sp
->pr_who
= t
->t_tid
;
1410 sp
->pr_nlwp
= p
->p_lwpcnt
;
1411 sp
->pr_brkbase
= (caddr32_t
)(uintptr_t)p
->p_brkbase
;
1412 sp
->pr_brksize
= (size32_t
)p
->p_brksize
;
1413 sp
->pr_stkbase
= (caddr32_t
)(uintptr_t)prgetstackbase(p
);
1414 sp
->pr_stksize
= (size32_t
)p
->p_stksize
;
1415 sp
->pr_oldcontext
= (caddr32_t
)lwp
->lwp_oldcontext
;
1416 sp
->pr_processor
= t
->t_cpu
->cpu_id
;
1417 sp
->pr_bind
= t
->t_bind_cpu
;
1420 * Fetch the current instruction, if not a system process.
1421 * We don't attempt this unless the lwp is stopped.
1423 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
1424 sp
->pr_flags
|= (PR_ISSYS
|PR_PCINVAL
);
1425 else if (!(flags
& PR_STOPPED
))
1426 sp
->pr_flags
|= PR_PCINVAL
;
1427 else if (!prfetchinstr(lwp
, &instr
))
1428 sp
->pr_flags
|= PR_PCINVAL
;
1430 sp
->pr_instr
= (uint32_t)instr
;
1433 * Drop p_lock while touching the lwp's stack.
1435 mutex_exit(&p
->p_lock
);
1437 sp
->pr_flags
|= PR_STEP
;
1438 if ((flags
& (PR_STOPPED
|PR_ASLEEP
)) && t
->t_sysnum
) {
1442 sp
->pr_syscall
= get_syscall32_args(lwp
,
1443 (int *)sp
->pr_sysarg
, &i
);
1444 sp
->pr_nsysarg
= (short)i
;
1445 if (t
->t_whystop
== PR_SYSEXIT
&& t
->t_sysnum
== SYS_execve
) {
1446 sp
->pr_sysarg
[0] = 0;
1447 sp
->pr_sysarg
[1] = (caddr32_t
)up
->u_argv
;
1448 sp
->pr_sysarg
[2] = (caddr32_t
)up
->u_envp
;
1449 for (i
= 0, auxp
= up
->u_auxv
;
1450 i
< sizeof (up
->u_auxv
) / sizeof (up
->u_auxv
[0]);
1452 if (auxp
->a_type
== AT_SUN_EXECNAME
) {
1455 (uintptr_t)auxp
->a_un
.a_ptr
;
1461 if ((flags
& PR_STOPPED
) || t
== curthread
)
1462 prgetprregs32(lwp
, sp
->pr_reg
);
1463 mutex_enter(&p
->p_lock
);
1467 oprgetpsinfo32(proc_t
*p
, prpsinfo32_t
*psp
, kthread_t
*tp
)
1474 int retval
, niceval
;
1477 hrtime_t hrutime
, hrstime
, cur_time
;
1479 ASSERT(MUTEX_HELD(&p
->p_lock
));
1481 bzero(psp
, sizeof (*psp
));
1483 if ((t
= tp
) == NULL
)
1484 t
= prchoose(p
); /* returns locked thread */
1488 /* kludge: map thread state enum into process state enum */
1493 state
= VSTOPPED(t
) ? TS_STOPPED
: t
->t_state
;
1498 case TS_SLEEP
: state
= SSLEEP
; break;
1499 case TS_RUN
: state
= SRUN
; break;
1500 case TS_ONPROC
: state
= SONPROC
; break;
1501 case TS_ZOMB
: state
= SZOMB
; break;
1502 case TS_STOPPED
: state
= SSTOP
; break;
1503 default: state
= 0; break;
1506 case SSLEEP
: c
= 'S'; break;
1507 case SRUN
: c
= 'R'; break;
1508 case SZOMB
: c
= 'Z'; break;
1509 case SSTOP
: c
= 'T'; break;
1510 case SIDL
: c
= 'I'; break;
1511 case SONPROC
: c
= 'O'; break;
1513 case SXBRK
: c
= 'X'; break;
1515 default: c
= '?'; break;
1517 psp
->pr_state
= state
;
1519 psp
->pr_zomb
= (state
== SZOMB
);
1521 * only export SSYS and SMSACCT; everything else is off-limits to
1524 psp
->pr_flag
= p
->p_flag
& (SSYS
| SMSACCT
);
1526 mutex_enter(&p
->p_crlock
);
1528 psp
->pr_uid
= crgetruid(cred
);
1529 psp
->pr_gid
= crgetrgid(cred
);
1530 psp
->pr_euid
= crgetuid(cred
);
1531 psp
->pr_egid
= crgetgid(cred
);
1532 mutex_exit(&p
->p_crlock
);
1534 psp
->pr_pid
= p
->p_pid
;
1535 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
1536 (p
->p_flag
& SZONETOP
)) {
1537 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
1539 * Inside local zones, fake zsched's pid as parent pids for
1540 * processes which reference processes outside of the zone.
1542 psp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
1544 psp
->pr_ppid
= p
->p_ppid
;
1546 psp
->pr_pgrp
= p
->p_pgrp
;
1547 psp
->pr_sid
= p
->p_sessp
->s_sid
;
1548 psp
->pr_addr
= 0; /* cannot represent 64-bit addr in 32 bits */
1549 hrutime
= mstate_aggr_state(p
, LMS_USER
);
1550 hrstime
= mstate_aggr_state(p
, LMS_SYSTEM
);
1551 hrt2ts32(hrutime
+ hrstime
, &psp
->pr_time
);
1552 TICK_TO_TIMESTRUC32(p
->p_cutime
+ p
->p_cstime
, &psp
->pr_ctime
);
1553 switch (p
->p_model
) {
1554 case DATAMODEL_ILP32
:
1555 psp
->pr_dmodel
= PR_MODEL_ILP32
;
1557 case DATAMODEL_LP64
:
1558 psp
->pr_dmodel
= PR_MODEL_LP64
;
1561 if (state
== SZOMB
|| t
== NULL
) {
1562 int wcode
= p
->p_wcode
; /* must be atomic read */
1565 psp
->pr_wstat
= wstat(wcode
, p
->p_wdata
);
1566 psp
->pr_lttydev
= PRNODEV32
;
1567 psp
->pr_ottydev
= (o_dev_t
)PRNODEV32
;
1573 psp
->pr_wchan
= 0; /* cannot represent in 32 bits */
1574 psp
->pr_pri
= t
->t_pri
;
1575 (void) strncpy(psp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
1576 sizeof (psp
->pr_clname
) - 1);
1577 retval
= CL_DONICE(t
, NULL
, 0, &niceval
);
1579 psp
->pr_oldpri
= v
.v_maxsyspri
- psp
->pr_pri
;
1580 psp
->pr_nice
= niceval
+ NZERO
;
1588 extern dev_t rwsconsdev
, rconsdev
, uconsdev
;
1590 * If the controlling terminal is the real
1591 * or workstation console device, map to what the
1592 * user thinks is the console device. Handle case when
1593 * rwsconsdev or rconsdev is set to NODEV for Starfire.
1595 if ((d
== rwsconsdev
|| d
== rconsdev
) && d
!= NODEV
)
1599 (void) cmpldev(&psp
->pr_lttydev
, d
);
1600 psp
->pr_ottydev
= cmpdev(d
);
1601 TIMESPEC_TO_TIMESPEC32(&psp
->pr_start
, &up
->u_start
);
1602 bcopy(up
->u_comm
, psp
->pr_fname
,
1603 MIN(sizeof (up
->u_comm
), sizeof (psp
->pr_fname
)-1));
1604 bcopy(up
->u_psargs
, psp
->pr_psargs
,
1605 MIN(PRARGSZ
-1, PSARGSZ
));
1606 psp
->pr_syscall
= t
->t_sysnum
;
1607 psp
->pr_argc
= up
->u_argc
;
1608 psp
->pr_argv
= (caddr32_t
)up
->u_argv
;
1609 psp
->pr_envp
= (caddr32_t
)up
->u_envp
;
1611 /* compute %cpu for the lwp or process */
1613 if ((t
= tp
) == NULL
)
1615 cur_time
= gethrtime_unscaled();
1617 pct
+= cpu_update_pct(t
, cur_time
);
1618 if (tp
!= NULL
) /* just do the one lwp */
1620 } while ((t
= t
->t_forw
) != p
->p_tlist
);
1622 psp
->pr_pctcpu
= prgetpctcpu(pct
);
1623 psp
->pr_cpu
= (psp
->pr_pctcpu
*100 + 0x6000) >> 15; /* [0..99] */
1624 if (psp
->pr_cpu
> 99)
1627 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
1632 mutex_exit(&p
->p_lock
);
1633 AS_LOCK_ENTER(as
, RW_READER
);
1634 psp
->pr_size
= (size32_t
)btopr(as
->a_resvsize
);
1635 psp
->pr_rssize
= (size32_t
)rm_asrss(as
);
1636 psp
->pr_pctmem
= rm_pctmemory(as
);
1638 mutex_enter(&p
->p_lock
);
1641 psp
->pr_bysize
= (size32_t
)ptob(psp
->pr_size
);
1642 psp
->pr_byrssize
= (size32_t
)ptob(psp
->pr_rssize
);
1645 * If we are looking at an LP64 process, zero out
1646 * the fields that cannot be represented in ILP32.
1648 if (p
->p_model
!= DATAMODEL_ILP32
) {
1652 psp
->pr_byrssize
= 0;
1667 caller_context_t
*ct
)
1669 int nsig
= PROC_IS_BRANDED(curproc
)? BROP(curproc
)->b_nsig
: NSIG
;
1670 caddr_t cmaddr
= (caddr_t
)arg
;
1675 prnode_t
*pnp
= VTOP(vp
);
1677 prnode_t
*xpnp
= NULL
;
1681 size_t thingsize
= 0;
1684 * For copyin()/copyout().
1692 prstatus32_t prstat
;
1698 prfpregset32_t fpregs
;
1703 prusage32_t prusage
;
1704 prhusage_t prhusage
;
1705 ioc_prmap32_t prmap
;
1706 auxv32_t auxv
[__KERN_NAUXV_IMPL
];
1710 * Native objects for internal use.
1729 prhusage_t prhusage
;
1730 auxv_t auxv
[__KERN_NAUXV_IMPL
];
1733 if (pnp
->pr_type
== PR_TMPL
)
1734 return (prctioctl(pnp
, cmd
, arg
, flag
, cr
));
1737 * Support for old /proc interface.
1739 if (pnp
->pr_pidfile
!= NULL
) {
1740 ASSERT(pnp
->pr_type
== PR_PIDDIR
);
1741 vp
= pnp
->pr_pidfile
;
1743 ASSERT(pnp
->pr_type
== PR_PIDFILE
);
1746 if (pnp
->pr_type
!= PR_PIDFILE
&& pnp
->pr_type
!= PR_LWPIDFILE
)
1750 * Fail ioctls which are logically "write" requests unless
1751 * the user has write permission.
1753 if ((flag
& FWRITE
) == 0 && isprwrioctl(cmd
))
1757 * Perform any necessary copyin() operations before
1758 * locking the process. Helps avoid deadlocks and
1759 * improves performance.
1761 * Also, detect invalid ioctl codes here to avoid
1762 * locking a process unnnecessarily.
1764 * Also, prepare to allocate space that will be needed below,
1770 thingsize
= sizeof (proc_t
);
1773 thingsize
= sizeof (user_t
);
1793 case PIOCSXREG
: /* set extra registers */
1794 case PIOCGXREG
: /* get extra registers */
1795 #if defined(__sparc)
1796 thingsize
= sizeof (prxregset_t
);
1802 thingsize
= (nsig
-1) * sizeof (struct sigaction32
);
1816 * We will need this below.
1817 * Allocate it now, before locking the process.
1819 xpnp
= prgetnode(vp
, PR_OPAGEDATA
);
1825 #if defined(__i386) || defined(__i386_COMPAT)
1829 #endif /* __i386 || __i386_COMPAT */
1831 #if defined(__sparc)
1833 thingsize
= sizeof (gwindows32_t
);
1835 #endif /* __sparc */
1837 case PIOCOPENM
: /* open mapped object for reading */
1839 un32
.va
= (uintptr_t)NULL
;
1840 else if (copyin(cmaddr
, &un32
.va
, sizeof (un32
.va
)))
1844 case PIOCRUN
: /* make lwp or process runnable */
1846 un32
.prrun
.pr_flags
= 0;
1847 else if (copyin(cmaddr
, &un32
.prrun
, sizeof (un32
.prrun
)))
1851 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
1852 if (copyin(cmaddr
, &un32
.lwpid
, sizeof (un32
.lwpid
)))
1856 case PIOCSTRACE
: /* set signal trace mask */
1857 if (copyin(cmaddr
, &un32
.smask
, sizeof (un32
.smask
)))
1861 case PIOCSSIG
: /* set current signal */
1863 un32
.info
.si_signo
= 0;
1864 else if (copyin(cmaddr
, &un32
.info
, sizeof (un32
.info
)))
1868 case PIOCKILL
: /* send signal */
1869 case PIOCUNKILL
: /* delete a signal */
1870 if (copyin(cmaddr
, &un32
.signo
, sizeof (un32
.signo
)))
1874 case PIOCNICE
: /* set nice priority */
1875 if (copyin(cmaddr
, &un32
.nice
, sizeof (un32
.nice
)))
1879 case PIOCSENTRY
: /* set syscall entry bit mask */
1880 case PIOCSEXIT
: /* set syscall exit bit mask */
1881 if (copyin(cmaddr
, &un32
.prmask
, sizeof (un32
.prmask
)))
1885 case PIOCSET
: /* set process flags */
1886 case PIOCRESET
: /* reset process flags */
1887 if (copyin(cmaddr
, &un32
.flags
, sizeof (un32
.flags
)))
1891 case PIOCSREG
: /* set general registers */
1892 if (copyin(cmaddr
, un32
.regs
, sizeof (un32
.regs
)))
1896 case PIOCSFPREG
: /* set floating-point registers */
1897 if (copyin(cmaddr
, &un32
.fpregs
, sizeof (un32
.fpregs
)))
1901 case PIOCSHOLD
: /* set signal-hold mask */
1902 if (copyin(cmaddr
, &un32
.holdmask
, sizeof (un32
.holdmask
)))
1906 case PIOCSFAULT
: /* set mask of traced faults */
1907 if (copyin(cmaddr
, &un32
.fltmask
, sizeof (un32
.fltmask
)))
1921 * If we need kmem_alloc()d space then we allocate it now, before
1922 * grabbing the process lock. Using kmem_alloc(KM_SLEEP) while
1923 * holding the process lock leads to deadlock with the clock thread.
1924 * (The clock thread wakes up the pageout daemon to free up space.
1925 * If the clock thread blocks behind us and we are sleeping waiting
1926 * for space, then space may never become available.)
1929 ASSERT(thing
== NULL
);
1930 thing
= kmem_alloc(thingsize
, KM_SLEEP
);
1940 case PIOCSXREG
: /* set extra registers */
1942 * perform copyin before grabbing the process lock
1945 if (copyin(cmaddr
, thing
, thingsize
)) {
1946 kmem_free(thing
, thingsize
);
1950 /* fall through... */
1956 if ((error
= prlock(pnp
, zdisp
)) != 0) {
1958 kmem_free(thing
, thingsize
);
1964 pcp
= pnp
->pr_common
;
1969 * Choose a thread/lwp for the operation.
1971 if (zdisp
== ZNO
&& cmd
!= PIOCSTOP
&& cmd
!= PIOCWSTOP
) {
1972 if (pnp
->pr_type
== PR_LWPIDFILE
&& cmd
!= PIOCLSTATUS
) {
1973 t
= pcp
->prc_thread
;
1976 t
= prchoose(p
); /* returns locked thread */
1986 case PIOCGETPR
: /* read struct proc */
1988 proc_t
*prp
= thing
;
1992 if (copyout(prp
, cmaddr
, sizeof (proc_t
)))
1994 kmem_free(prp
, sizeof (proc_t
));
1999 case PIOCGETU
: /* read u-area */
2001 user_t
*userp
= thing
;
2006 if (copyout(userp
, cmaddr
, sizeof (user_t
)))
2008 kmem_free(userp
, sizeof (user_t
));
2013 case PIOCOPENM
: /* open mapped object for reading */
2014 if (PROCESS_NOT_32BIT(p
) && cmaddr
!= NULL
) {
2019 error
= propenm(pnp
, cmaddr
,
2020 (caddr_t
)(uintptr_t)un32
.va
, rvalp
, cr
);
2021 /* propenm() called prunlock(pnp) */
2024 case PIOCSTOP
: /* stop process or lwp from running */
2025 case PIOCWSTOP
: /* wait for process or lwp to stop */
2027 * Can't apply to a system process.
2029 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
) {
2035 if (cmd
== PIOCSTOP
)
2039 * If an lwp is waiting for itself or its process, don't wait.
2040 * The lwp will never see the fact that itself is stopped.
2042 if ((pnp
->pr_type
== PR_LWPIDFILE
)?
2043 (pcp
->prc_thread
== curthread
) : (p
== curproc
)) {
2044 if (cmd
== PIOCWSTOP
)
2050 if ((error
= pr_wait_stop(pnp
, (time_t)0)) != 0)
2051 break; /* pr_wait_stop() unlocked the process */
2055 else if (PROCESS_NOT_32BIT(p
)) {
2060 * Return process/lwp status information.
2062 t
= pr_thread(pnp
); /* returns locked thread */
2064 oprgetstatus32(t
, &un32
.prstat
, VTOZONE(vp
));
2066 if (copyout(&un32
.prstat
, cmaddr
, sizeof (un32
.prstat
)))
2071 case PIOCRUN
: /* make lwp or process runnable */
2073 long flags
= un32
.prrun
.pr_flags
;
2076 * Cannot set an lwp running is it is not stopped.
2077 * Also, no lwp other than the /proc agent lwp can
2078 * be set running so long as the /proc agent lwp exists.
2080 if ((!ISTOPPED(t
) && !VSTOPPED(t
) &&
2081 !(t
->t_proc_flag
& TP_PRSTOP
)) ||
2082 (p
->p_agenttp
!= NULL
&&
2083 (t
!= p
->p_agenttp
|| pnp
->pr_type
!= PR_LWPIDFILE
))) {
2089 if ((flags
& PRSVADDR
) && PROCESS_NOT_32BIT(p
)) {
2095 if (flags
& (PRSHOLD
|PRSTRACE
|PRSFAULT
|PRSVADDR
)) {
2096 un
.prrun
.pr_flags
= (int)flags
;
2097 un
.prrun
.pr_trace
= un32
.prrun
.pr_trace
;
2098 un
.prrun
.pr_sighold
= un32
.prrun
.pr_sighold
;
2099 un
.prrun
.pr_fault
= un32
.prrun
.pr_fault
;
2101 (caddr_t
)(uintptr_t)un32
.prrun
.pr_vaddr
;
2102 prsetrun(t
, &un
.prrun
);
2105 error
= pr_setrun(pnp
, prmaprunflags(flags
));
2111 case PIOCLWPIDS
: /* get array of lwp identifiers */
2118 Nlwp
= nlwp
= p
->p_lwpcnt
;
2120 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (id_t
)) {
2121 kmem_free(thing
, thingsize
);
2124 if (thing
== NULL
) {
2125 thingsize
= (Nlwp
+1) * sizeof (id_t
);
2126 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2128 if (thing
== NULL
) {
2136 if ((t
= p
->p_tlist
) != NULL
) {
2138 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2142 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2147 if (copyout(Bidp
, cmaddr
, (Nlwp
+1) * sizeof (id_t
)))
2149 kmem_free(Bidp
, (Nlwp
+1) * sizeof (id_t
));
2153 case PIOCOPENLWP
: /* return /proc lwp file descriptor */
2159 if ((xvp
= prlwpnode(pnp
, un32
.lwpid
)) == NULL
)
2161 else if (error
= fassign(&xvp
, flag
& (FREAD
|FWRITE
), &n
)) {
2168 case PIOCOPENPD
: /* return /proc page data file descriptor */
2170 vnode_t
*xvp
= PTOV(xpnp
);
2171 vnode_t
*dp
= pnp
->pr_parent
;
2174 if (PROCESS_NOT_32BIT(p
)) {
2182 if (pnp
->pr_type
== PR_LWPIDFILE
) {
2183 dp
= VTOP(dp
)->pr_parent
;
2184 dp
= VTOP(dp
)->pr_parent
;
2186 ASSERT(VTOP(dp
)->pr_type
== PR_PIDDIR
);
2189 pcp
= pnp
->pr_pcommon
;
2190 xpnp
->pr_ino
= ptoi(pcp
->prc_pid
);
2191 xpnp
->pr_common
= pcp
;
2192 xpnp
->pr_pcommon
= pcp
;
2193 xpnp
->pr_parent
= dp
;
2195 xpnp
->pr_next
= p
->p_plist
;
2199 if (error
= fassign(&xvp
, FREAD
, &n
)) {
2208 case PIOCGTRACE
: /* get signal trace mask */
2209 prassignset(&un32
.smask
, &p
->p_sigmask
);
2211 if (copyout(&un32
.smask
, cmaddr
, sizeof (un32
.smask
)))
2215 case PIOCSTRACE
: /* set signal trace mask */
2216 prdelset(&un32
.smask
, SIGKILL
);
2217 prassignset(&p
->p_sigmask
, &un32
.smask
);
2218 if (!sigisempty(&p
->p_sigmask
))
2219 p
->p_proc_flag
|= P_PR_TRACE
;
2220 else if (prisempty(&p
->p_fltmask
)) {
2222 if (up
->u_systrap
== 0)
2223 p
->p_proc_flag
&= ~P_PR_TRACE
;
2228 case PIOCSSIG
: /* set current signal */
2229 if (un32
.info
.si_signo
!= 0 && PROCESS_NOT_32BIT(p
)) {
2233 bzero(&un
.info
, sizeof (un
.info
));
2234 siginfo_32tok(&un32
.info
, (k_siginfo_t
*)&un
.info
);
2235 error
= pr_setsig(pnp
, &un
.info
);
2237 if (un32
.info
.si_signo
== SIGKILL
&& error
== 0)
2242 case PIOCKILL
: /* send signal */
2243 error
= pr_kill(pnp
, un32
.signo
, cr
);
2245 if (un32
.signo
== SIGKILL
&& error
== 0)
2249 case PIOCUNKILL
: /* delete a signal */
2250 error
= pr_unkill(pnp
, un32
.signo
);
2254 case PIOCNICE
: /* set nice priority */
2255 error
= pr_nice(p
, un32
.nice
, cr
);
2259 case PIOCGENTRY
: /* get syscall entry bit mask */
2260 case PIOCGEXIT
: /* get syscall exit bit mask */
2262 if (cmd
== PIOCGENTRY
) {
2263 prassignset(&un32
.prmask
, &up
->u_entrymask
);
2265 prassignset(&un32
.prmask
, &up
->u_exitmask
);
2268 if (copyout(&un32
.prmask
, cmaddr
, sizeof (un32
.prmask
)))
2272 case PIOCSENTRY
: /* set syscall entry bit mask */
2273 case PIOCSEXIT
: /* set syscall exit bit mask */
2274 pr_setentryexit(p
, &un32
.prmask
, cmd
== PIOCSENTRY
);
2278 case PIOCSRLC
: /* obsolete: set running on last /proc close */
2279 error
= pr_set(p
, prmapsetflags(PR_RLC
));
2283 case PIOCRRLC
: /* obsolete: reset run-on-last-close flag */
2284 error
= pr_unset(p
, prmapsetflags(PR_RLC
));
2288 case PIOCSFORK
: /* obsolete: set inherit-on-fork flag */
2289 error
= pr_set(p
, prmapsetflags(PR_FORK
));
2293 case PIOCRFORK
: /* obsolete: reset inherit-on-fork flag */
2294 error
= pr_unset(p
, prmapsetflags(PR_FORK
));
2298 case PIOCSET
: /* set process flags */
2299 error
= pr_set(p
, prmapsetflags((long)un32
.flags
));
2303 case PIOCRESET
: /* reset process flags */
2304 error
= pr_unset(p
, prmapsetflags((long)un32
.flags
));
2308 case PIOCGREG
: /* get general registers */
2309 if (PROCESS_NOT_32BIT(p
))
2311 else if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
2312 bzero(un32
.regs
, sizeof (un32
.regs
));
2314 /* drop p_lock while touching the lwp's stack */
2315 mutex_exit(&p
->p_lock
);
2316 prgetprregs32(lwp
, un32
.regs
);
2317 mutex_enter(&p
->p_lock
);
2321 copyout(un32
.regs
, cmaddr
, sizeof (un32
.regs
)))
2325 case PIOCSREG
: /* set general registers */
2326 if (PROCESS_NOT_32BIT(p
))
2328 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
2331 /* drop p_lock while touching the lwp's stack */
2332 mutex_exit(&p
->p_lock
);
2333 prgregset_32ton(lwp
, un32
.regs
, un
.regs
);
2334 prsetprregs(lwp
, un
.regs
, 0);
2335 mutex_enter(&p
->p_lock
);
2340 case PIOCGFPREG
: /* get floating-point registers */
2342 error
= EINVAL
; /* No FP support */
2343 else if (PROCESS_NOT_32BIT(p
))
2345 else if (t
->t_state
!= TS_STOPPED
&& !VSTOPPED(t
))
2346 bzero(&un32
.fpregs
, sizeof (un32
.fpregs
));
2348 /* drop p_lock while touching the lwp's stack */
2349 mutex_exit(&p
->p_lock
);
2350 prgetprfpregs32(lwp
, &un32
.fpregs
);
2351 mutex_enter(&p
->p_lock
);
2355 copyout(&un32
.fpregs
, cmaddr
, sizeof (un32
.fpregs
)))
2359 case PIOCSFPREG
: /* set floating-point registers */
2361 error
= EINVAL
; /* No FP support */
2362 else if (PROCESS_NOT_32BIT(p
))
2364 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
2367 /* drop p_lock while touching the lwp's stack */
2368 mutex_exit(&p
->p_lock
);
2369 prsetprfpregs32(lwp
, &un32
.fpregs
);
2370 mutex_enter(&p
->p_lock
);
2375 case PIOCGXREGSIZE
: /* get the size of the extra registers */
2380 xregsize
= prgetprxregsize(p
);
2382 if (copyout(&xregsize
, cmaddr
, sizeof (xregsize
)))
2386 error
= EINVAL
; /* No extra register support */
2391 case PIOCGXREG
: /* get extra registers */
2392 if (PROCESS_NOT_32BIT(p
))
2394 else if (!prhasx(p
))
2395 error
= EINVAL
; /* No extra register support */
2397 bzero(thing
, thingsize
);
2398 if (t
->t_state
== TS_STOPPED
|| VSTOPPED(t
)) {
2399 /* drop p_lock to touch the stack */
2400 mutex_exit(&p
->p_lock
);
2401 prgetprxregs(lwp
, thing
);
2402 mutex_enter(&p
->p_lock
);
2407 copyout(thing
, cmaddr
, thingsize
))
2410 kmem_free(thing
, thingsize
);
2415 case PIOCSXREG
: /* set extra registers */
2416 if (PROCESS_NOT_32BIT(p
))
2418 else if (!ISTOPPED(t
) && !VSTOPPED(t
) && !DSTOPPED(t
))
2420 else if (!prhasx(p
))
2421 error
= EINVAL
; /* No extra register support */
2423 /* drop p_lock while touching the lwp's stack */
2424 mutex_exit(&p
->p_lock
);
2425 prsetprxregs(lwp
, thing
);
2426 mutex_enter(&p
->p_lock
);
2430 kmem_free(thing
, thingsize
);
2435 case PIOCSTATUS
: /* get process/lwp status */
2436 if (PROCESS_NOT_32BIT(p
)) {
2441 oprgetstatus32(t
, &un32
.prstat
, VTOZONE(vp
));
2443 if (copyout(&un32
.prstat
, cmaddr
, sizeof (un32
.prstat
)))
2447 case PIOCLSTATUS
: /* get status for process & all lwps */
2451 prstatus32_t
*Bprsp
;
2454 if (PROCESS_NOT_32BIT(p
)) {
2457 kmem_free(thing
, thingsize
);
2464 nlwp
= Nlwp
= p
->p_lwpcnt
;
2466 if (thing
&& thingsize
!= (Nlwp
+1) * sizeof (prstatus32_t
)) {
2467 kmem_free(thing
, thingsize
);
2470 if (thing
== NULL
) {
2471 thingsize
= (Nlwp
+1) * sizeof (prstatus32_t
);
2472 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2474 if (thing
== NULL
) {
2479 Bprsp
= (prstatus32_t
*)thing
;
2482 oprgetstatus32(t
, prsp
, VTOZONE(vp
));
2485 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2488 oprgetstatus32(t
, ++prsp
, VTOZONE(vp
));
2489 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2492 if (copyout(Bprsp
, cmaddr
, (Nlwp
+1) * sizeof (prstatus32_t
)))
2495 kmem_free(Bprsp
, (Nlwp
+ 1) * sizeof (prstatus32_t
));
2499 case PIOCPSINFO
: /* get ps(1) information */
2501 prpsinfo32_t
*psp
= &un32
.prps
;
2503 oprgetpsinfo32(p
, psp
,
2504 (pnp
->pr_type
== PR_LWPIDFILE
)? pcp
->prc_thread
: NULL
);
2507 if (copyout(&un32
.prps
, cmaddr
, sizeof (un32
.prps
)))
2512 case PIOCMAXSIG
: /* get maximum signal number */
2517 if (copyout(&n
, cmaddr
, sizeof (int)))
2522 case PIOCACTION
: /* get signal action structures */
2525 struct sigaction32
*sap
= thing
;
2527 if (PROCESS_NOT_32BIT(p
))
2531 for (sig
= 1; sig
< nsig
; sig
++)
2532 prgetaction32(p
, up
, sig
, &sap
[sig
-1]);
2536 copyout(sap
, cmaddr
, (nsig
-1)*sizeof (struct sigaction32
)))
2538 kmem_free(sap
, (nsig
-1)*sizeof (struct sigaction32
));
2543 case PIOCGHOLD
: /* get signal-hold mask */
2544 schedctl_finish_sigblock(t
);
2545 sigktou(&t
->t_hold
, &un32
.holdmask
);
2547 if (copyout(&un32
.holdmask
, cmaddr
, sizeof (un32
.holdmask
)))
2551 case PIOCSHOLD
: /* set signal-hold mask */
2552 pr_sethold(pnp
, &un32
.holdmask
);
2556 case PIOCNMAP
: /* get number of memory mappings */
2559 struct as
*as
= p
->p_as
;
2561 if ((p
->p_flag
& SSYS
) || as
== &kas
)
2564 mutex_exit(&p
->p_lock
);
2565 AS_LOCK_ENTER(as
, RW_WRITER
);
2568 mutex_enter(&p
->p_lock
);
2571 if (copyout(&n
, cmaddr
, sizeof (int)))
2576 case PIOCMAP
: /* get memory map information */
2579 struct as
*as
= p
->p_as
;
2581 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
2584 } else if (PROCESS_NOT_32BIT(p
)) {
2588 mutex_exit(&p
->p_lock
);
2589 AS_LOCK_ENTER(as
, RW_WRITER
);
2590 error
= oprgetmap32(p
, &iolhead
);
2592 mutex_enter(&p
->p_lock
);
2595 error
= pr_iol_copyout_and_free(&iolhead
,
2599 * The procfs PIOCMAP ioctl returns an all-zero buffer
2600 * to indicate the end of the prmap[] array.
2601 * Append it to whatever has already been copied out.
2603 bzero(&un32
.prmap
, sizeof (un32
.prmap
));
2605 copyout(&un32
.prmap
, cmaddr
, sizeof (un32
.prmap
)))
2610 case PIOCGFAULT
: /* get mask of traced faults */
2611 prassignset(&un32
.fltmask
, &p
->p_fltmask
);
2613 if (copyout(&un32
.fltmask
, cmaddr
, sizeof (un32
.fltmask
)))
2617 case PIOCSFAULT
: /* set mask of traced faults */
2618 pr_setfault(p
, &un32
.fltmask
);
2622 case PIOCCFAULT
: /* clear current fault */
2623 lwp
->lwp_curflt
= 0;
2627 case PIOCCRED
: /* get process credentials */
2631 mutex_enter(&p
->p_crlock
);
2633 un32
.prcred
.pr_euid
= crgetuid(cp
);
2634 un32
.prcred
.pr_ruid
= crgetruid(cp
);
2635 un32
.prcred
.pr_suid
= crgetsuid(cp
);
2636 un32
.prcred
.pr_egid
= crgetgid(cp
);
2637 un32
.prcred
.pr_rgid
= crgetrgid(cp
);
2638 un32
.prcred
.pr_sgid
= crgetsgid(cp
);
2639 un32
.prcred
.pr_ngroups
= crgetngroups(cp
);
2640 mutex_exit(&p
->p_crlock
);
2643 if (copyout(&un32
.prcred
, cmaddr
, sizeof (un32
.prcred
)))
2648 case PIOCGROUPS
: /* get supplementary groups */
2652 mutex_enter(&p
->p_crlock
);
2655 mutex_exit(&p
->p_crlock
);
2658 if (copyout(crgetgroups(cp
), cmaddr
,
2659 MAX(crgetngroups(cp
), 1) * sizeof (gid_t
)))
2665 case PIOCUSAGE
: /* get usage info */
2668 * For an lwp file descriptor, return just the lwp usage.
2669 * For a process file descriptor, return total usage,
2670 * all current lwps plus all defunct lwps.
2672 prhusage_t
*pup
= &un32
.prhusage
;
2675 bzero(pup
, sizeof (*pup
));
2676 pup
->pr_tstamp
= gethrtime();
2678 if (pnp
->pr_type
== PR_LWPIDFILE
) {
2679 t
= pcp
->prc_thread
;
2685 pup
->pr_count
= p
->p_defunct
;
2686 pup
->pr_create
= p
->p_mstart
;
2687 pup
->pr_term
= p
->p_mterm
;
2689 pup
->pr_rtime
= p
->p_mlreal
;
2690 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2691 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2692 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2693 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2694 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2695 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2696 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2697 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2698 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2699 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2701 pup
->pr_minf
= p
->p_ru
.minflt
;
2702 pup
->pr_majf
= p
->p_ru
.majflt
;
2703 pup
->pr_nswap
= p
->p_ru
.nswap
;
2704 pup
->pr_inblk
= p
->p_ru
.inblock
;
2705 pup
->pr_oublk
= p
->p_ru
.oublock
;
2706 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2707 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2708 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2709 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2710 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2711 pup
->pr_sysc
= p
->p_ru
.sysc
;
2712 pup
->pr_ioch
= p
->p_ru
.ioch
;
2715 * Add the usage information for each active lwp.
2717 if ((t
= p
->p_tlist
) != NULL
&&
2718 !(pcp
->prc_flags
& PRC_DESTROY
)) {
2720 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2723 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2729 upup
= kmem_alloc(sizeof (*upup
), KM_SLEEP
);
2730 prcvtusage32(pup
, upup
);
2731 if (copyout(upup
, cmaddr
, sizeof (*upup
)))
2733 kmem_free(upup
, sizeof (*upup
));
2738 case PIOCLUSAGE
: /* get detailed usage info */
2747 nlwp
= Nlwp
= (pcp
->prc_flags
& PRC_DESTROY
)? 0 : p
->p_lwpcnt
;
2749 if (thing
&& thingsize
!=
2750 sizeof (prhusage_t
) + (Nlwp
+1) * sizeof (prusage32_t
)) {
2751 kmem_free(thing
, thingsize
);
2754 if (thing
== NULL
) {
2755 thingsize
= sizeof (prhusage_t
) +
2756 (Nlwp
+1) * sizeof (prusage32_t
);
2757 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2759 if (thing
== NULL
) {
2764 pup
= (prhusage_t
*)thing
;
2765 upup
= Bupup
= (prusage32_t
*)(pup
+ 1);
2767 ASSERT(p
== pcp
->prc_proc
);
2769 curtime
= gethrtime();
2772 * First the summation over defunct lwps.
2774 bzero(pup
, sizeof (*pup
));
2775 pup
->pr_count
= p
->p_defunct
;
2776 pup
->pr_tstamp
= curtime
;
2777 pup
->pr_create
= p
->p_mstart
;
2778 pup
->pr_term
= p
->p_mterm
;
2780 pup
->pr_rtime
= p
->p_mlreal
;
2781 pup
->pr_utime
= p
->p_acct
[LMS_USER
];
2782 pup
->pr_stime
= p
->p_acct
[LMS_SYSTEM
];
2783 pup
->pr_ttime
= p
->p_acct
[LMS_TRAP
];
2784 pup
->pr_tftime
= p
->p_acct
[LMS_TFAULT
];
2785 pup
->pr_dftime
= p
->p_acct
[LMS_DFAULT
];
2786 pup
->pr_kftime
= p
->p_acct
[LMS_KFAULT
];
2787 pup
->pr_ltime
= p
->p_acct
[LMS_USER_LOCK
];
2788 pup
->pr_slptime
= p
->p_acct
[LMS_SLEEP
];
2789 pup
->pr_wtime
= p
->p_acct
[LMS_WAIT_CPU
];
2790 pup
->pr_stoptime
= p
->p_acct
[LMS_STOPPED
];
2792 pup
->pr_minf
= p
->p_ru
.minflt
;
2793 pup
->pr_majf
= p
->p_ru
.majflt
;
2794 pup
->pr_nswap
= p
->p_ru
.nswap
;
2795 pup
->pr_inblk
= p
->p_ru
.inblock
;
2796 pup
->pr_oublk
= p
->p_ru
.oublock
;
2797 pup
->pr_msnd
= p
->p_ru
.msgsnd
;
2798 pup
->pr_mrcv
= p
->p_ru
.msgrcv
;
2799 pup
->pr_sigs
= p
->p_ru
.nsignals
;
2800 pup
->pr_vctx
= p
->p_ru
.nvcsw
;
2801 pup
->pr_ictx
= p
->p_ru
.nivcsw
;
2802 pup
->pr_sysc
= p
->p_ru
.sysc
;
2803 pup
->pr_ioch
= p
->p_ru
.ioch
;
2805 prcvtusage32(pup
, upup
);
2808 * Fill one prusage struct for each active lwp.
2810 if ((t
= p
->p_tlist
) != NULL
&&
2811 !(pcp
->prc_flags
& PRC_DESTROY
)) {
2813 ASSERT(!(t
->t_proc_flag
& TP_LWPEXIT
));
2818 prcvtusage32(pup
, upup
);
2819 } while ((t
= t
->t_forw
) != p
->p_tlist
);
2824 if (copyout(Bupup
, cmaddr
, (Nlwp
+1) * sizeof (prusage32_t
)))
2826 kmem_free(thing
, thingsize
);
2831 case PIOCNAUXV
: /* get number of aux vector entries */
2833 int n
= __KERN_NAUXV_IMPL
;
2836 if (copyout(&n
, cmaddr
, sizeof (int)))
2841 case PIOCAUXV
: /* get aux vector (see sys/auxv.h) */
2845 if (PROCESS_NOT_32BIT(p
)) {
2850 for (i
= 0; i
< __KERN_NAUXV_IMPL
; i
++) {
2851 un32
.auxv
[i
].a_type
= up
->u_auxv
[i
].a_type
;
2852 un32
.auxv
[i
].a_un
.a_val
=
2853 (int32_t)up
->u_auxv
[i
].a_un
.a_val
;
2856 if (copyout(un32
.auxv
, cmaddr
,
2857 __KERN_NAUXV_IMPL
* sizeof (auxv32_t
)))
2863 #if defined(__i386) || defined(__i386_COMPAT)
2864 case PIOCNLDT
: /* get number of LDT entries */
2868 mutex_exit(&p
->p_lock
);
2869 mutex_enter(&p
->p_ldtlock
);
2871 mutex_exit(&p
->p_ldtlock
);
2872 mutex_enter(&p
->p_lock
);
2874 if (copyout(&n
, cmaddr
, sizeof (n
)))
2879 case PIOCLDT
: /* get LDT entries */
2884 mutex_exit(&p
->p_lock
);
2885 mutex_enter(&p
->p_ldtlock
);
2888 if (thing
&& thingsize
!= (n
+1) * sizeof (*ssd
)) {
2889 kmem_free(thing
, thingsize
);
2892 if (thing
== NULL
) {
2893 thingsize
= (n
+1) * sizeof (*ssd
);
2894 thing
= kmem_alloc(thingsize
, KM_NOSLEEP
);
2896 if (thing
== NULL
) {
2897 mutex_exit(&p
->p_ldtlock
);
2898 mutex_enter(&p
->p_lock
);
2907 mutex_exit(&p
->p_ldtlock
);
2908 mutex_enter(&p
->p_lock
);
2911 /* mark the end of the list with a null entry */
2912 bzero(&ssd
[n
], sizeof (*ssd
));
2913 if (copyout(ssd
, cmaddr
, (n
+1) * sizeof (*ssd
)))
2915 kmem_free(ssd
, (n
+1) * sizeof (*ssd
));
2918 #endif /* __i386 || __i386_COMPAT */
2920 #if defined(__sparc)
2921 case PIOCGWIN
: /* get gwindows_t (see sys/reg.h) */
2923 gwindows32_t
*gwp
= thing
;
2925 if (PROCESS_NOT_32BIT(p
)) {
2929 /* drop p->p_lock while touching the stack */
2930 mutex_exit(&p
->p_lock
);
2931 bzero(gwp
, sizeof (*gwp
));
2932 prgetwindows32(lwp
, gwp
);
2933 mutex_enter(&p
->p_lock
);
2935 if (copyout(gwp
, cmaddr
, sizeof (*gwp
)))
2938 kmem_free(gwp
, sizeof (*gwp
));
2942 #endif /* __sparc */
2951 ASSERT(thing
== NULL
);
2952 ASSERT(xpnp
== NULL
);
2955 #endif /* _SYSCALL32_IMPL */
2958 * Distinguish "writeable" ioctl requests from others.
2961 isprwrioctl(int cmd
)
2991 * Map the ioctl() interface run flags to the new interface run flags.
2994 prmaprunflags(long flags
)
2996 ulong_t newflags
= 0;
3000 if (flags
& PRCFAULT
)
3004 if (flags
& PRSABORT
)
3012 * Map the ioctl() interface settable mode flags to the new interface flags.
3015 prmapsetflags(long flags
)
3020 (PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_MSACCT|PR_PCOMPAT)
3022 if (flags
& ~ALLFLAGS
)
3023 newflags
= 0xffff; /* forces EINVAL */
3024 if (flags
& PR_FORK
)
3025 newflags
|= (0x00100000 | 0x08000000);
3027 newflags
|= 0x00200000;
3029 newflags
|= 0x00400000;
3030 if (flags
& PR_ASYNC
)
3031 newflags
|= 0x00800000;
3032 if (flags
& PR_MSACCT
)
3033 newflags
|= 0x01000000;
3034 if (flags
& PR_BPTADJ
)
3035 newflags
|= 0x02000000;
3036 if (flags
& PR_PCOMPAT
)
3037 newflags
|= 0x04000000;
3042 * Apply PIOCRUN options specific to the ioctl() interface.
3045 prsetrun(kthread_t
*t
, prrun_t
*prp
)
3047 proc_t
*p
= ttoproc(t
);
3048 klwp_t
*lwp
= ttolwp(t
);
3049 long flags
= prp
->pr_flags
;
3050 user_t
*up
= PTOU(p
);
3052 ASSERT(MUTEX_HELD(&p
->p_lock
));
3054 if (flags
& PRSHOLD
) {
3055 schedctl_finish_sigblock(t
);
3056 sigutok(&prp
->pr_sighold
, &t
->t_hold
);
3057 t
->t_sig_check
= 1; /* so ISSIG will be done */
3059 if (flags
& PRSTRACE
) {
3060 prdelset(&prp
->pr_trace
, SIGKILL
);
3061 prassignset(&p
->p_sigmask
, &prp
->pr_trace
);
3062 if (!sigisempty(&p
->p_sigmask
))
3063 p
->p_proc_flag
|= P_PR_TRACE
;
3064 else if (prisempty(&p
->p_fltmask
)) {
3065 if (up
->u_systrap
== 0)
3066 p
->p_proc_flag
&= ~P_PR_TRACE
;
3069 if (flags
& PRSFAULT
) {
3070 prassignset(&p
->p_fltmask
, &prp
->pr_fault
);
3071 if (!prisempty(&p
->p_fltmask
))
3072 p
->p_proc_flag
|= P_PR_TRACE
;
3073 else if (sigisempty(&p
->p_sigmask
)) {
3074 if (up
->u_systrap
== 0)
3075 p
->p_proc_flag
&= ~P_PR_TRACE
;
3079 * prsvaddr() must be called before prstep() because
3080 * stepping can depend on the current value of the PC.
3081 * We drop p_lock while touching the lwp's registers (on stack).
3083 if (flags
& PRSVADDR
) {
3084 mutex_exit(&p
->p_lock
);
3085 prsvaddr(lwp
, prp
->pr_vaddr
);
3086 mutex_enter(&p
->p_lock
);
3091 * Common code for PIOCOPENM
3092 * Returns with the process unlocked.
3095 propenm(prnode_t
*pnp
, caddr_t cmaddr
, caddr_t va
, int *rvalp
, cred_t
*cr
)
3097 proc_t
*p
= pnp
->pr_common
->prc_proc
;
3098 struct as
*as
= p
->p_as
;
3105 * By fiat, a system process has no address space.
3107 if ((p
->p_flag
& SSYS
) || as
== &kas
) {
3109 } else if (cmaddr
) {
3111 * We drop p_lock before grabbing the address
3112 * space lock in order to avoid a deadlock with
3113 * the clock thread. The process will not
3114 * disappear and its address space will not
3115 * change because it is marked P_PR_LOCK.
3117 mutex_exit(&p
->p_lock
);
3118 AS_LOCK_ENTER(as
, RW_READER
);
3119 seg
= as_segat(as
, va
);
3121 seg
->s_ops
== &segvn_ops
&&
3122 segop_getvp(seg
, va
, &xvp
) == 0 &&
3124 xvp
->v_type
== VREG
) {
3130 mutex_enter(&p
->p_lock
);
3131 } else if ((xvp
= p
->p_exec
) == NULL
) {
3140 if ((error
= fop_access(xvp
, VREAD
, 0, cr
, NULL
)) == 0)
3141 error
= fassign(&xvp
, FREAD
, &n
);
3153 * Return old version of process/lwp status.
3154 * The u-block is mapped in by this routine and unmapped at the end.
3157 oprgetstatus(kthread_t
*t
, prstatus_t
*sp
, zone_t
*zp
)
3159 proc_t
*p
= ttoproc(t
);
3160 klwp_t
*lwp
= ttolwp(t
);
3165 ASSERT(MUTEX_HELD(&p
->p_lock
));
3168 bzero(sp
, sizeof (*sp
));
3170 if (t
->t_state
== TS_STOPPED
) {
3171 flags
|= PR_STOPPED
;
3172 if ((t
->t_schedflag
& TS_PSTART
) == 0)
3174 } else if (VSTOPPED(t
)) {
3175 flags
|= PR_STOPPED
|PR_ISTOP
;
3177 if (!(flags
& PR_ISTOP
) && (t
->t_proc_flag
& TP_PRSTOP
))
3179 if (lwp
->lwp_asleep
)
3181 if (p
->p_proc_flag
& P_PR_FORK
)
3183 if (p
->p_proc_flag
& P_PR_RUNLCL
)
3185 if (p
->p_proc_flag
& P_PR_KILLCL
)
3187 if (p
->p_proc_flag
& P_PR_ASYNC
)
3189 if (p
->p_proc_flag
& P_PR_BPTADJ
)
3191 if (p
->p_proc_flag
& P_PR_PTRACE
)
3192 flags
|= PR_PCOMPAT
;
3193 if (t
->t_proc_flag
& TP_MSACCT
)
3195 sp
->pr_flags
= flags
;
3197 sp
->pr_why
= PR_REQUESTED
;
3200 sp
->pr_why
= t
->t_whystop
;
3201 sp
->pr_what
= t
->t_whatstop
;
3204 if (t
->t_whystop
== PR_FAULTED
)
3205 bcopy(&lwp
->lwp_siginfo
,
3206 &sp
->pr_info
, sizeof (k_siginfo_t
));
3207 else if (lwp
->lwp_curinfo
)
3208 bcopy(&lwp
->lwp_curinfo
->sq_info
,
3209 &sp
->pr_info
, sizeof (k_siginfo_t
));
3211 if (SI_FROMUSER(&lwp
->lwp_siginfo
) && zp
->zone_id
!= GLOBAL_ZONEID
&&
3212 sp
->pr_info
.si_zoneid
!= zp
->zone_id
) {
3213 sp
->pr_info
.si_pid
= zp
->zone_zsched
->p_pid
;
3214 sp
->pr_info
.si_uid
= 0;
3215 sp
->pr_info
.si_ctid
= -1;
3216 sp
->pr_info
.si_zoneid
= zp
->zone_id
;
3219 sp
->pr_cursig
= lwp
->lwp_cursig
;
3220 prassignset(&sp
->pr_sigpend
, &p
->p_sig
);
3221 prassignset(&sp
->pr_lwppend
, &t
->t_sig
);
3222 schedctl_finish_sigblock(t
);
3223 prassignset(&sp
->pr_sighold
, &t
->t_hold
);
3224 sp
->pr_altstack
= lwp
->lwp_sigaltstack
;
3225 prgetaction(p
, up
, lwp
->lwp_cursig
, &sp
->pr_action
);
3226 sp
->pr_pid
= p
->p_pid
;
3227 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
3228 (p
->p_flag
& SZONETOP
)) {
3229 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
3231 * Inside local zones, fake zsched's pid as parent pids for
3232 * processes which reference processes outside of the zone.
3234 sp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
3236 sp
->pr_ppid
= p
->p_ppid
;
3238 sp
->pr_pgrp
= p
->p_pgrp
;
3239 sp
->pr_sid
= p
->p_sessp
->s_sid
;
3240 hrt2ts(mstate_aggr_state(p
, LMS_USER
), &sp
->pr_utime
);
3241 hrt2ts(mstate_aggr_state(p
, LMS_SYSTEM
), &sp
->pr_stime
);
3242 TICK_TO_TIMESTRUC(p
->p_cutime
, &sp
->pr_cutime
);
3243 TICK_TO_TIMESTRUC(p
->p_cstime
, &sp
->pr_cstime
);
3244 (void) strncpy(sp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
3245 sizeof (sp
->pr_clname
) - 1);
3246 sp
->pr_who
= t
->t_tid
;
3247 sp
->pr_nlwp
= p
->p_lwpcnt
;
3248 sp
->pr_brkbase
= p
->p_brkbase
;
3249 sp
->pr_brksize
= p
->p_brksize
;
3250 sp
->pr_stkbase
= prgetstackbase(p
);
3251 sp
->pr_stksize
= p
->p_stksize
;
3252 sp
->pr_oldcontext
= (struct ucontext
*)lwp
->lwp_oldcontext
;
3253 sp
->pr_processor
= t
->t_cpu
->cpu_id
;
3254 sp
->pr_bind
= t
->t_bind_cpu
;
3257 * Fetch the current instruction, if not a system process.
3258 * We don't attempt this unless the lwp is stopped.
3260 if ((p
->p_flag
& SSYS
) || p
->p_as
== &kas
)
3261 sp
->pr_flags
|= (PR_ISSYS
|PR_PCINVAL
);
3262 else if (!(flags
& PR_STOPPED
))
3263 sp
->pr_flags
|= PR_PCINVAL
;
3264 else if (!prfetchinstr(lwp
, &instr
))
3265 sp
->pr_flags
|= PR_PCINVAL
;
3267 sp
->pr_instr
= instr
;
3270 * Drop p_lock while touching the lwp's stack.
3272 mutex_exit(&p
->p_lock
);
3274 sp
->pr_flags
|= PR_STEP
;
3275 if ((flags
& (PR_STOPPED
|PR_ASLEEP
)) && t
->t_sysnum
) {
3279 sp
->pr_syscall
= get_syscall_args(lwp
,
3280 (long *)sp
->pr_sysarg
, &i
);
3281 sp
->pr_nsysarg
= (short)i
;
3282 if (t
->t_whystop
== PR_SYSEXIT
&& t
->t_sysnum
== SYS_execve
) {
3283 sp
->pr_sysarg
[0] = 0;
3284 sp
->pr_sysarg
[1] = (uintptr_t)up
->u_argv
;
3285 sp
->pr_sysarg
[2] = (uintptr_t)up
->u_envp
;
3286 for (i
= 0, auxp
= up
->u_auxv
;
3287 i
< sizeof (up
->u_auxv
) / sizeof (up
->u_auxv
[0]);
3289 if (auxp
->a_type
== AT_SUN_EXECNAME
) {
3291 (uintptr_t)auxp
->a_un
.a_ptr
;
3297 if ((flags
& PR_STOPPED
) || t
== curthread
)
3298 prgetprregs(lwp
, sp
->pr_reg
);
3299 mutex_enter(&p
->p_lock
);
3303 * Return old version of information used by ps(1).
3306 oprgetpsinfo(proc_t
*p
, prpsinfo_t
*psp
, kthread_t
*tp
)
3313 int retval
, niceval
;
3316 hrtime_t hrutime
, hrstime
, cur_time
;
3318 ASSERT(MUTEX_HELD(&p
->p_lock
));
3320 bzero(psp
, sizeof (*psp
));
3322 if ((t
= tp
) == NULL
)
3323 t
= prchoose(p
); /* returns locked thread */
3327 /* kludge: map thread state enum into process state enum */
3332 state
= VSTOPPED(t
) ? TS_STOPPED
: t
->t_state
;
3337 case TS_SLEEP
: state
= SSLEEP
; break;
3338 case TS_RUN
: state
= SRUN
; break;
3339 case TS_ONPROC
: state
= SONPROC
; break;
3340 case TS_ZOMB
: state
= SZOMB
; break;
3341 case TS_STOPPED
: state
= SSTOP
; break;
3342 default: state
= 0; break;
3345 case SSLEEP
: c
= 'S'; break;
3346 case SRUN
: c
= 'R'; break;
3347 case SZOMB
: c
= 'Z'; break;
3348 case SSTOP
: c
= 'T'; break;
3349 case SIDL
: c
= 'I'; break;
3350 case SONPROC
: c
= 'O'; break;
3352 case SXBRK
: c
= 'X'; break;
3354 default: c
= '?'; break;
3356 psp
->pr_state
= state
;
3358 psp
->pr_zomb
= (state
== SZOMB
);
3360 * only export SSYS and SMSACCT; everything else is off-limits to
3363 psp
->pr_flag
= p
->p_flag
& (SSYS
| SMSACCT
);
3365 mutex_enter(&p
->p_crlock
);
3367 psp
->pr_uid
= crgetruid(cred
);
3368 psp
->pr_gid
= crgetrgid(cred
);
3369 psp
->pr_euid
= crgetuid(cred
);
3370 psp
->pr_egid
= crgetgid(cred
);
3371 mutex_exit(&p
->p_crlock
);
3373 psp
->pr_pid
= p
->p_pid
;
3374 if (curproc
->p_zone
->zone_id
!= GLOBAL_ZONEID
&&
3375 (p
->p_flag
& SZONETOP
)) {
3376 ASSERT(p
->p_zone
->zone_id
!= GLOBAL_ZONEID
);
3378 * Inside local zones, fake zsched's pid as parent pids for
3379 * processes which reference processes outside of the zone.
3381 psp
->pr_ppid
= curproc
->p_zone
->zone_zsched
->p_pid
;
3383 psp
->pr_ppid
= p
->p_ppid
;
3385 psp
->pr_pgrp
= p
->p_pgrp
;
3386 psp
->pr_sid
= p
->p_sessp
->s_sid
;
3387 psp
->pr_addr
= prgetpsaddr(p
);
3388 hrutime
= mstate_aggr_state(p
, LMS_USER
);
3389 hrstime
= mstate_aggr_state(p
, LMS_SYSTEM
);
3390 hrt2ts(hrutime
+ hrstime
, &psp
->pr_time
);
3391 TICK_TO_TIMESTRUC(p
->p_cutime
+ p
->p_cstime
, &psp
->pr_ctime
);
3392 switch (p
->p_model
) {
3393 case DATAMODEL_ILP32
:
3394 psp
->pr_dmodel
= PR_MODEL_ILP32
;
3396 case DATAMODEL_LP64
:
3397 psp
->pr_dmodel
= PR_MODEL_LP64
;
3400 if (state
== SZOMB
|| t
== NULL
) {
3401 int wcode
= p
->p_wcode
; /* must be atomic read */
3404 psp
->pr_wstat
= wstat(wcode
, p
->p_wdata
);
3405 psp
->pr_lttydev
= PRNODEV
;
3406 psp
->pr_ottydev
= (o_dev_t
)PRNODEV
;
3412 psp
->pr_wchan
= t
->t_wchan
;
3413 psp
->pr_pri
= t
->t_pri
;
3414 (void) strncpy(psp
->pr_clname
, sclass
[t
->t_cid
].cl_name
,
3415 sizeof (psp
->pr_clname
) - 1);
3416 retval
= CL_DONICE(t
, NULL
, 0, &niceval
);
3418 psp
->pr_oldpri
= v
.v_maxsyspri
- psp
->pr_pri
;
3419 psp
->pr_nice
= niceval
+ NZERO
;
3427 extern dev_t rwsconsdev
, rconsdev
, uconsdev
;
3429 * If the controlling terminal is the real
3430 * or workstation console device, map to what the
3431 * user thinks is the console device. Handle case when
3432 * rwsconsdev or rconsdev is set to NODEV for Starfire.
3434 if ((d
== rwsconsdev
|| d
== rconsdev
) && d
!= NODEV
)
3438 psp
->pr_lttydev
= (d
== NODEV
) ? PRNODEV
: d
;
3439 psp
->pr_ottydev
= cmpdev(d
);
3440 psp
->pr_start
= up
->u_start
;
3441 bcopy(up
->u_comm
, psp
->pr_fname
,
3442 MIN(sizeof (up
->u_comm
), sizeof (psp
->pr_fname
)-1));
3443 bcopy(up
->u_psargs
, psp
->pr_psargs
,
3444 MIN(PRARGSZ
-1, PSARGSZ
));
3445 psp
->pr_syscall
= t
->t_sysnum
;
3446 psp
->pr_argc
= up
->u_argc
;
3447 psp
->pr_argv
= (char **)up
->u_argv
;
3448 psp
->pr_envp
= (char **)up
->u_envp
;
3450 /* compute %cpu for the lwp or process */
3452 if ((t
= tp
) == NULL
)
3454 cur_time
= gethrtime_unscaled();
3456 pct
+= cpu_update_pct(t
, cur_time
);
3457 if (tp
!= NULL
) /* just do the one lwp */
3459 } while ((t
= t
->t_forw
) != p
->p_tlist
);
3461 psp
->pr_pctcpu
= prgetpctcpu(pct
);
3462 psp
->pr_cpu
= (psp
->pr_pctcpu
*100 + 0x6000) >> 15; /* [0..99] */
3463 if (psp
->pr_cpu
> 99)
3466 if ((p
->p_flag
& SSYS
) || (as
= p
->p_as
) == &kas
) {
3471 mutex_exit(&p
->p_lock
);
3472 AS_LOCK_ENTER(as
, RW_READER
);
3473 psp
->pr_size
= btopr(as
->a_resvsize
);
3474 psp
->pr_rssize
= rm_asrss(as
);
3475 psp
->pr_pctmem
= rm_pctmemory(as
);
3477 mutex_enter(&p
->p_lock
);
3480 psp
->pr_bysize
= ptob(psp
->pr_size
);
3481 psp
->pr_byrssize
= ptob(psp
->pr_rssize
);
3485 * Return an array of structures with memory map information.
3486 * We allocate here; the caller must deallocate.
3487 * The caller is also responsible to append the zero-filled entry
3488 * that terminates the PIOCMAP output buffer.
3491 oprgetmap(proc_t
*p
, list_t
*iolhead
)
3493 struct as
*as
= p
->p_as
;
3496 struct seg
*brkseg
, *stkseg
;
3499 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3502 * Request an initial buffer size that doesn't waste memory
3503 * if the address space has only a small number of segments.
3505 pr_iol_initlist(iolhead
, sizeof (*mp
), avl_numnodes(&as
->a_segtree
));
3507 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3510 brkseg
= break_seg(p
);
3511 stkseg
= as_segat(as
, prgetstackbase(p
));
3514 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3515 caddr_t saddr
, naddr
;
3518 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3519 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3523 mp
= pr_iol_newbuf(iolhead
, sizeof (*mp
));
3525 mp
->pr_vaddr
= saddr
;
3526 mp
->pr_size
= naddr
- saddr
;
3527 mp
->pr_off
= segop_getoffset(seg
, saddr
);
3529 if (prot
& PROT_READ
)
3530 mp
->pr_mflags
|= MA_READ
;
3531 if (prot
& PROT_WRITE
)
3532 mp
->pr_mflags
|= MA_WRITE
;
3533 if (prot
& PROT_EXEC
)
3534 mp
->pr_mflags
|= MA_EXEC
;
3535 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3536 mp
->pr_mflags
|= MA_SHARED
;
3538 mp
->pr_mflags
|= MA_BREAK
;
3539 else if (seg
== stkseg
)
3540 mp
->pr_mflags
|= MA_STACK
;
3541 mp
->pr_pagesize
= PAGESIZE
;
3543 ASSERT(tmp
== NULL
);
3544 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3549 #ifdef _SYSCALL32_IMPL
3551 oprgetmap32(proc_t
*p
, list_t
*iolhead
)
3553 struct as
*as
= p
->p_as
;
3556 struct seg
*brkseg
, *stkseg
;
3559 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3562 * Request an initial buffer size that doesn't waste memory
3563 * if the address space has only a small number of segments.
3565 pr_iol_initlist(iolhead
, sizeof (*mp
), avl_numnodes(&as
->a_segtree
));
3567 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3570 brkseg
= break_seg(p
);
3571 stkseg
= as_segat(as
, prgetstackbase(p
));
3574 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3575 caddr_t saddr
, naddr
;
3578 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3579 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3583 mp
= pr_iol_newbuf(iolhead
, sizeof (*mp
));
3585 mp
->pr_vaddr
= (caddr32_t
)(uintptr_t)saddr
;
3586 mp
->pr_size
= (size32_t
)(naddr
- saddr
);
3587 mp
->pr_off
= (off32_t
)segop_getoffset(seg
, saddr
);
3589 if (prot
& PROT_READ
)
3590 mp
->pr_mflags
|= MA_READ
;
3591 if (prot
& PROT_WRITE
)
3592 mp
->pr_mflags
|= MA_WRITE
;
3593 if (prot
& PROT_EXEC
)
3594 mp
->pr_mflags
|= MA_EXEC
;
3595 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3596 mp
->pr_mflags
|= MA_SHARED
;
3598 mp
->pr_mflags
|= MA_BREAK
;
3599 else if (seg
== stkseg
)
3600 mp
->pr_mflags
|= MA_STACK
;
3601 mp
->pr_pagesize
= PAGESIZE
;
3603 ASSERT(tmp
== NULL
);
3604 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3608 #endif /* _SYSCALL32_IMPL */
3611 * Return the size of the old /proc page data file.
3614 oprpdsize(struct as
*as
)
3619 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3621 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3624 size
= sizeof (prpageheader_t
);
3626 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3627 caddr_t saddr
, naddr
;
3631 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3632 (void) pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3633 if ((npage
= (naddr
- saddr
) / PAGESIZE
) != 0)
3634 size
+= sizeof (prasmap_t
) + roundlong(npage
);
3636 ASSERT(tmp
== NULL
);
3637 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3642 #ifdef _SYSCALL32_IMPL
3644 oprpdsize32(struct as
*as
)
3649 ASSERT(as
!= &kas
&& AS_WRITE_HELD(as
));
3651 if ((seg
= AS_SEGFIRST(as
)) == NULL
)
3654 size
= sizeof (ioc_prpageheader32_t
);
3656 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3657 caddr_t saddr
, naddr
;
3661 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3662 (void) pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3663 if ((npage
= (naddr
- saddr
) / PAGESIZE
) != 0)
3664 size
+= sizeof (ioc_prmap32_t
) + round4(npage
);
3666 ASSERT(tmp
== NULL
);
3667 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3671 #endif /* _SYSCALL32_IMPL */
3674 * Read old /proc page data information.
3677 oprpdread(struct as
*as
, uint_t hatid
, struct uio
*uiop
)
3681 prpageheader_t
*php
;
3687 AS_LOCK_ENTER(as
, RW_WRITER
);
3689 if ((seg
= AS_SEGFIRST(as
)) == NULL
) {
3693 size
= oprpdsize(as
);
3694 if (uiop
->uio_resid
< size
) {
3699 buf
= kmem_zalloc(size
, KM_SLEEP
);
3700 php
= (prpageheader_t
*)buf
;
3701 pmp
= (prasmap_t
*)(buf
+ sizeof (prpageheader_t
));
3703 hrt2ts(gethrtime(), &php
->pr_tstamp
);
3707 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3708 caddr_t saddr
, naddr
;
3711 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3717 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3718 if ((len
= naddr
- saddr
) == 0)
3720 npage
= len
/ PAGESIZE
;
3721 next
= (uintptr_t)(pmp
+ 1) + roundlong(npage
);
3723 * It's possible that the address space can change
3724 * subtlely even though we're holding as->a_lock
3725 * due to the nondeterminism of page_exists() in
3726 * the presence of asychronously flushed pages or
3727 * mapped files whose sizes are changing.
3728 * page_exists() may be called indirectly from
3729 * pr_getprot() by a segop_incore() routine.
3730 * If this happens we need to make sure we don't
3731 * overrun the buffer whose size we computed based
3732 * on the initial iteration through the segments.
3733 * Once we've detected an overflow, we need to clean
3734 * up the temporary memory allocated in pr_getprot()
3735 * and retry. If there's a pending signal, we return
3736 * EINTR so that this thread can be dislodged if
3737 * a latent bug causes us to spin indefinitely.
3739 if (next
> (uintptr_t)buf
+ size
) {
3740 pr_getprot_done(&tmp
);
3743 kmem_free(buf
, size
);
3745 if (ISSIG(curthread
, JUSTLOOKING
))
3752 php
->pr_npage
+= npage
;
3753 pmp
->pr_vaddr
= saddr
;
3754 pmp
->pr_npage
= npage
;
3755 pmp
->pr_off
= segop_getoffset(seg
, saddr
);
3757 if (prot
& PROT_READ
)
3758 pmp
->pr_mflags
|= MA_READ
;
3759 if (prot
& PROT_WRITE
)
3760 pmp
->pr_mflags
|= MA_WRITE
;
3761 if (prot
& PROT_EXEC
)
3762 pmp
->pr_mflags
|= MA_EXEC
;
3763 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3764 pmp
->pr_mflags
|= MA_SHARED
;
3765 pmp
->pr_pagesize
= PAGESIZE
;
3766 hat_getstat(as
, saddr
, len
, hatid
,
3767 (char *)(pmp
+ 1), HAT_SYNC_ZERORM
);
3768 pmp
= (prasmap_t
*)next
;
3770 ASSERT(tmp
== NULL
);
3771 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3775 ASSERT((uintptr_t)pmp
<= (uintptr_t)buf
+ size
);
3776 error
= uiomove(buf
, (caddr_t
)pmp
- buf
, UIO_READ
, uiop
);
3777 kmem_free(buf
, size
);
3782 #ifdef _SYSCALL32_IMPL
3784 oprpdread32(struct as
*as
, uint_t hatid
, struct uio
*uiop
)
3788 ioc_prpageheader32_t
*php
;
3789 ioc_prasmap32_t
*pmp
;
3794 AS_LOCK_ENTER(as
, RW_WRITER
);
3796 if ((seg
= AS_SEGFIRST(as
)) == NULL
) {
3800 size
= oprpdsize32(as
);
3801 if (uiop
->uio_resid
< size
) {
3806 buf
= kmem_zalloc(size
, KM_SLEEP
);
3807 php
= (ioc_prpageheader32_t
*)buf
;
3808 pmp
= (ioc_prasmap32_t
*)(buf
+ sizeof (ioc_prpageheader32_t
));
3810 hrt2ts32(gethrtime(), &php
->pr_tstamp
);
3814 caddr_t eaddr
= seg
->s_base
+ pr_getsegsize(seg
, 0);
3815 caddr_t saddr
, naddr
;
3818 for (saddr
= seg
->s_base
; saddr
< eaddr
; saddr
= naddr
) {
3824 prot
= pr_getprot(seg
, 0, &tmp
, &saddr
, &naddr
, eaddr
);
3825 if ((len
= naddr
- saddr
) == 0)
3827 npage
= len
/ PAGESIZE
;
3828 next
= (uintptr_t)(pmp
+ 1) + round4(npage
);
3830 * It's possible that the address space can change
3831 * subtlely even though we're holding as->a_lock
3832 * due to the nondeterminism of page_exists() in
3833 * the presence of asychronously flushed pages or
3834 * mapped files whose sizes are changing.
3835 * page_exists() may be called indirectly from
3836 * pr_getprot() by a segop_incore() routine.
3837 * If this happens we need to make sure we don't
3838 * overrun the buffer whose size we computed based
3839 * on the initial iteration through the segments.
3840 * Once we've detected an overflow, we need to clean
3841 * up the temporary memory allocated in pr_getprot()
3842 * and retry. If there's a pending signal, we return
3843 * EINTR so that this thread can be dislodged if
3844 * a latent bug causes us to spin indefinitely.
3846 if (next
> (uintptr_t)buf
+ size
) {
3847 pr_getprot_done(&tmp
);
3850 kmem_free(buf
, size
);
3852 if (ISSIG(curthread
, JUSTLOOKING
))
3859 php
->pr_npage
+= npage
;
3860 pmp
->pr_vaddr
= (uint32_t)(uintptr_t)saddr
;
3861 pmp
->pr_npage
= (uint32_t)npage
;
3862 pmp
->pr_off
= (int32_t)segop_getoffset(seg
, saddr
);
3864 if (prot
& PROT_READ
)
3865 pmp
->pr_mflags
|= MA_READ
;
3866 if (prot
& PROT_WRITE
)
3867 pmp
->pr_mflags
|= MA_WRITE
;
3868 if (prot
& PROT_EXEC
)
3869 pmp
->pr_mflags
|= MA_EXEC
;
3870 if (segop_gettype(seg
, saddr
) & MAP_SHARED
)
3871 pmp
->pr_mflags
|= MA_SHARED
;
3872 pmp
->pr_pagesize
= PAGESIZE
;
3873 hat_getstat(as
, saddr
, len
, hatid
,
3874 (char *)(pmp
+ 1), HAT_SYNC_ZERORM
);
3875 pmp
= (ioc_prasmap32_t
*)next
;
3877 ASSERT(tmp
== NULL
);
3878 } while ((seg
= AS_SEGNEXT(as
, seg
)) != NULL
);
3882 ASSERT((uintptr_t)pmp
== (uintptr_t)buf
+ size
);
3883 error
= uiomove(buf
, (caddr_t
)pmp
- buf
, UIO_READ
, uiop
);
3884 kmem_free(buf
, size
);
3888 #endif /* _SYSCALL32_IMPL */
3891 #ifdef _SYSCALL32_IMPL
3900 caller_context_t
*ct
)
3902 switch (curproc
->p_model
) {
3903 case DATAMODEL_ILP32
:
3904 return (prioctl32(vp
, cmd
, arg
, flag
, cr
, rvalp
, ct
));
3905 case DATAMODEL_LP64
:
3906 return (prioctl64(vp
, cmd
, arg
, flag
, cr
, rvalp
, ct
));
3911 #endif /* _SYSCALL32_IMPL */