OpenGrok

Cross Reference: prioctl.c
xref: /onnv/onnv-gate/usr/src/uts/common/fs/proc/prioctl.c
Home | History | Annotate | Line # | Download | only in proc
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28 /*	  All rights reserved.  	*/
     29 
     30 #include <sys/types.h>
     31 #include <sys/param.h>
     32 #include <sys/vmparam.h>
     33 #include <sys/var.h>
     34 #include <sys/cmn_err.h>
     35 #include <sys/cred.h>
     36 #include <sys/debug.h>
     37 #include <sys/errno.h>
     38 #include <sys/file.h>
     39 #include <sys/inline.h>
     40 #include <sys/kmem.h>
     41 #include <sys/proc.h>
     42 #include <sys/brand.h>
     43 #include <sys/sysmacros.h>
     44 #include <sys/systm.h>
     45 #include <sys/vfs.h>
     46 #include <sys/vnode.h>
     47 #include <sys/cpuvar.h>
     48 #include <sys/session.h>
     49 #include <sys/signal.h>
     50 #include <sys/auxv.h>
     51 #include <sys/user.h>
     52 #include <sys/disp.h>
     53 #include <sys/class.h>
     54 #include <sys/ts.h>
     55 #include <sys/mman.h>
     56 #include <sys/fault.h>
     57 #include <sys/syscall.h>
     58 #include <sys/schedctl.h>
     59 #include <sys/pset.h>
     60 #include <sys/old_procfs.h>
     61 #include <sys/zone.h>
     62 #include <sys/time.h>
     63 #include <sys/msacct.h>
     64 #include <vm/rm.h>
     65 #include <vm/as.h>
     66 #include <vm/rm.h>
     67 #include <vm/seg.h>
     68 #include <vm/seg_vn.h>
     69 #include <sys/contract_impl.h>
     70 #include <sys/ctfs_impl.h>
     71 #include <sys/ctfs.h>
     72 
     73 #if defined(__i386) || defined(__i386_COMPAT)
     74 #include <sys/sysi86.h>
     75 #endif
     76 
     77 #include <fs/proc/prdata.h>
     78 
     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 *);
     87 
     88 static int
     89 prctioctl(prnode_t *pnp, int cmd, intptr_t arg, int flag, cred_t *cr)
     90 {
     91 	int error = 0;
     92 	ct_kparam_t kparam;
     93 	ct_param_t *param = &kparam.param;
     94 	ct_template_t *tmpl;
     95 
     96 	if (cmd != CT_TSET && cmd != CT_TGET)
     97 		return (EINVAL);
     98 
     99 	error = ctparam_copyin((void *)arg, &kparam, flag, cmd);
    100 	if (error != 0)
    101 		return (error);
    102 
    103 	if ((error = prlock(pnp, ZNO)) != 0) {
    104 		kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    105 		return (error);
    106 	}
    107 
    108 	tmpl = pnp->pr_common->prc_thread->t_lwp->lwp_ct_active[pnp->pr_cttype];
    109 	if (tmpl == NULL) {
    110 		prunlock(pnp);
    111 		kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    112 		return (ESTALE);
    113 	}
    114 
    115 	if (cmd == CT_TSET)
    116 		error = ctmpl_set(tmpl, &kparam, cr);
    117 	else
    118 		error = ctmpl_get(tmpl, &kparam);
    119 
    120 	prunlock(pnp);
    121 
    122 	if (cmd == CT_TGET && error == 0) {
    123 		error = ctparam_copyout(&kparam, (void *)arg, flag);
    124 	} else {
    125 		kmem_free(kparam.ctpm_kbuf, param->ctpm_size);
    126 	}
    127 
    128 	return (error);
    129 }
    130 
    131 
    132 /*
    133  * Control operations (lots).
    134  */
    135 /*ARGSUSED*/
    136 #ifdef _SYSCALL32_IMPL
    137 static int
    138 prioctl64(
    139 	struct vnode *vp,
    140 	int cmd,
    141 	intptr_t arg,
    142 	int flag,
    143 	cred_t *cr,
    144 	int *rvalp,
    145 	caller_context_t *ct)
    146 #else
    147 int
    148 prioctl(
    149 	struct vnode *vp,
    150 	int cmd,
    151 	intptr_t arg,
    152 	int flag,
    153 	cred_t *cr,
    154 	int *rvalp,
    155 	caller_context_t *ct)
    156 #endif	/* _SYSCALL32_IMPL */
    157 {
    158 	int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
    159 	caddr_t cmaddr = (caddr_t)arg;
    160 	proc_t *p;
    161 	user_t *up;
    162 	kthread_t *t;
    163 	klwp_t *lwp;
    164 	prnode_t *pnp = VTOP(vp);
    165 	prcommon_t *pcp;
    166 	prnode_t *xpnp = NULL;
    167 	int error;
    168 	int zdisp;
    169 	void *thing = NULL;
    170 	size_t thingsize = 0;
    171 
    172 	/*
    173 	 * For copyin()/copyout().
    174 	 */
    175 	union {
    176 		caddr_t		va;
    177 		int		signo;
    178 		int		nice;
    179 		uint_t		lwpid;
    180 		long		flags;
    181 		prstatus_t	prstat;
    182 		prrun_t		prrun;
    183 		sigset_t	smask;
    184 		siginfo_t	info;
    185 		sysset_t	prmask;
    186 		prgregset_t	regs;
    187 		prfpregset_t	fpregs;
    188 		prpsinfo_t	prps;
    189 		sigset_t	holdmask;
    190 		fltset_t	fltmask;
    191 		prcred_t	prcred;
    192 		prhusage_t	prhusage;
    193 		prmap_t		prmap;
    194 		auxv_t		auxv[__KERN_NAUXV_IMPL];
    195 	} un;
    196 
    197 	if (pnp->pr_type == PR_TMPL)
    198 		return (prctioctl(pnp, cmd, arg, flag, cr));
    199 
    200 	/*
    201 	 * Support for old /proc interface.
    202 	 */
    203 	if (pnp->pr_pidfile != NULL) {
    204 		ASSERT(pnp->pr_type == PR_PIDDIR);
    205 		vp = pnp->pr_pidfile;
    206 		pnp = VTOP(vp);
    207 		ASSERT(pnp->pr_type == PR_PIDFILE);
    208 	}
    209 
    210 	if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
    211 		return (ENOTTY);
    212 
    213 	/*
    214 	 * Fail ioctls which are logically "write" requests unless
    215 	 * the user has write permission.
    216 	 */
    217 	if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
    218 		return (EBADF);
    219 
    220 	/*
    221 	 * Perform any necessary copyin() operations before
    222 	 * locking the process.  Helps avoid deadlocks and
    223 	 * improves performance.
    224 	 *
    225 	 * Also, detect invalid ioctl codes here to avoid
    226 	 * locking a process unnnecessarily.
    227 	 *
    228 	 * Also, prepare to allocate space that will be needed below,
    229 	 * case by case.
    230 	 */
    231 	error = 0;
    232 	switch (cmd) {
    233 	case PIOCGETPR:
    234 		thingsize = sizeof (proc_t);
    235 		break;
    236 	case PIOCGETU:
    237 		thingsize = sizeof (user_t);
    238 		break;
    239 	case PIOCSTOP:
    240 	case PIOCWSTOP:
    241 	case PIOCLWPIDS:
    242 	case PIOCGTRACE:
    243 	case PIOCGENTRY:
    244 	case PIOCGEXIT:
    245 	case PIOCSRLC:
    246 	case PIOCRRLC:
    247 	case PIOCSFORK:
    248 	case PIOCRFORK:
    249 	case PIOCGREG:
    250 	case PIOCGFPREG:
    251 	case PIOCSTATUS:
    252 	case PIOCLSTATUS:
    253 	case PIOCPSINFO:
    254 	case PIOCMAXSIG:
    255 	case PIOCGXREGSIZE:
    256 		break;
    257 	case PIOCSXREG:		/* set extra registers */
    258 	case PIOCGXREG:		/* get extra registers */
    259 #if defined(__sparc)
    260 		thingsize = sizeof (prxregset_t);
    261 #else
    262 		thingsize = 0;
    263 #endif
    264 		break;
    265 	case PIOCACTION:
    266 		thingsize = (nsig-1) * sizeof (struct sigaction);
    267 		break;
    268 	case PIOCGHOLD:
    269 	case PIOCNMAP:
    270 	case PIOCMAP:
    271 	case PIOCGFAULT:
    272 	case PIOCCFAULT:
    273 	case PIOCCRED:
    274 	case PIOCGROUPS:
    275 	case PIOCUSAGE:
    276 	case PIOCLUSAGE:
    277 		break;
    278 	case PIOCOPENPD:
    279 		/*
    280 		 * We will need this below.
    281 		 * Allocate it now, before locking the process.
    282 		 */
    283 		xpnp = prgetnode(vp, PR_OPAGEDATA);
    284 		break;
    285 	case PIOCNAUXV:
    286 	case PIOCAUXV:
    287 		break;
    288 
    289 #if defined(__i386) || defined(__amd64)
    290 	case PIOCNLDT:
    291 	case PIOCLDT:
    292 		break;
    293 #endif	/* __i386 || __amd64 */
    294 
    295 #if defined(__sparc)
    296 	case PIOCGWIN:
    297 		thingsize = sizeof (gwindows_t);
    298 		break;
    299 #endif	/* __sparc */
    300 
    301 	case PIOCOPENM:		/* open mapped object for reading */
    302 		if (cmaddr == NULL)
    303 			un.va = NULL;
    304 		else if (copyin(cmaddr, &un.va, sizeof (un.va)))
    305 			error = EFAULT;
    306 		break;
    307 
    308 	case PIOCRUN:		/* make lwp or process runnable */
    309 		if (cmaddr == NULL)
    310 			un.prrun.pr_flags = 0;
    311 		else if (copyin(cmaddr, &un.prrun, sizeof (un.prrun)))
    312 			error = EFAULT;
    313 		break;
    314 
    315 	case PIOCOPENLWP:	/* return /proc lwp file descriptor */
    316 		if (copyin(cmaddr, &un.lwpid, sizeof (un.lwpid)))
    317 			error = EFAULT;
    318 		break;
    319 
    320 	case PIOCSTRACE:	/* set signal trace mask */
    321 		if (copyin(cmaddr, &un.smask, sizeof (un.smask)))
    322 			error = EFAULT;
    323 		break;
    324 
    325 	case PIOCSSIG:		/* set current signal */
    326 		if (cmaddr == NULL)
    327 			un.info.si_signo = 0;
    328 		else if (copyin(cmaddr, &un.info, sizeof (un.info)))
    329 			error = EFAULT;
    330 		break;
    331 
    332 	case PIOCKILL:		/* send signal */
    333 	case PIOCUNKILL:	/* delete a signal */
    334 		if (copyin(cmaddr, &un.signo, sizeof (un.signo)))
    335 			error = EFAULT;
    336 		break;
    337 
    338 	case PIOCNICE:		/* set nice priority */
    339 		if (copyin(cmaddr, &un.nice, sizeof (un.nice)))
    340 			error = EFAULT;
    341 		break;
    342 
    343 	case PIOCSENTRY:	/* set syscall entry bit mask */
    344 	case PIOCSEXIT:		/* set syscall exit bit mask */
    345 		if (copyin(cmaddr, &un.prmask, sizeof (un.prmask)))
    346 			error = EFAULT;
    347 		break;
    348 
    349 	case PIOCSET:		/* set process flags */
    350 	case PIOCRESET:		/* reset process flags */
    351 		if (copyin(cmaddr, &un.flags, sizeof (un.flags)))
    352 			error = EFAULT;
    353 		break;
    354 
    355 	case PIOCSREG:		/* set general registers */
    356 		if (copyin(cmaddr, un.regs, sizeof (un.regs)))
    357 			error = EFAULT;
    358 		break;
    359 
    360 	case PIOCSFPREG:	/* set floating-point registers */
    361 		if (copyin(cmaddr, &un.fpregs, sizeof (un.fpregs)))
    362 			error = EFAULT;
    363 		break;
    364 
    365 	case PIOCSHOLD:		/* set signal-hold mask */
    366 		if (copyin(cmaddr, &un.holdmask, sizeof (un.holdmask)))
    367 			error = EFAULT;
    368 		break;
    369 
    370 	case PIOCSFAULT:	/* set mask of traced faults */
    371 		if (copyin(cmaddr, &un.fltmask, sizeof (un.fltmask)))
    372 			error = EFAULT;
    373 		break;
    374 
    375 	default:
    376 		error = EINVAL;
    377 		break;
    378 	}
    379 
    380 	if (error)
    381 		return (error);
    382 
    383 startover:
    384 	/*
    385 	 * If we need kmem_alloc()d space then we allocate it now, before
    386 	 * grabbing the process lock.  Using kmem_alloc(KM_SLEEP) while
    387 	 * holding the process lock leads to deadlock with the clock thread.
    388 	 * (The clock thread wakes up the pageout daemon to free up space.
    389 	 * If the clock thread blocks behind us and we are sleeping waiting
    390 	 * for space, then space may never become available.)
    391 	 */
    392 	if (thingsize) {
    393 		ASSERT(thing == NULL);
    394 		thing = kmem_alloc(thingsize, KM_SLEEP);
    395 	}
    396 
    397 	switch (cmd) {
    398 	case PIOCPSINFO:
    399 	case PIOCGETPR:
    400 	case PIOCUSAGE:
    401 	case PIOCLUSAGE:
    402 		zdisp = ZYES;
    403 		break;
    404 	case PIOCSXREG:		/* set extra registers */
    405 		/*
    406 		 * perform copyin before grabbing the process lock
    407 		 */
    408 		if (thing) {
    409 			if (copyin(cmaddr, thing, thingsize)) {
    410 				kmem_free(thing, thingsize);
    411 				return (EFAULT);
    412 			}
    413 		}
    414 		/* fall through... */
    415 	default:
    416 		zdisp = ZNO;
    417 		break;
    418 	}
    419 
    420 	if ((error = prlock(pnp, zdisp)) != 0) {
    421 		if (thing != NULL)
    422 			kmem_free(thing, thingsize);
    423 		if (xpnp)
    424 			prfreenode(xpnp);
    425 		return (error);
    426 	}
    427 
    428 	pcp = pnp->pr_common;
    429 	p = pcp->prc_proc;
    430 	ASSERT(p != NULL);
    431 
    432 	/*
    433 	 * Choose a thread/lwp for the operation.
    434 	 */
    435 	if (zdisp == ZNO && cmd != PIOCSTOP && cmd != PIOCWSTOP) {
    436 		if (pnp->pr_type == PR_LWPIDFILE && cmd != PIOCLSTATUS) {
    437 			t = pcp->prc_thread;
    438 			ASSERT(t != NULL);
    439 		} else {
    440 			t = prchoose(p);	/* returns locked thread */
    441 			ASSERT(t != NULL);
    442 			thread_unlock(t);
    443 		}
    444 		lwp = ttolwp(t);
    445 	}
    446 
    447 	error = 0;
    448 	switch (cmd) {
    449 
    450 	case PIOCGETPR:		/* read struct proc */
    451 	{
    452 		proc_t *prp = thing;
    453 
    454 		*prp = *p;
    455 		prunlock(pnp);
    456 		if (copyout(prp, cmaddr, sizeof (proc_t)))
    457 			error = EFAULT;
    458 		kmem_free(prp, sizeof (proc_t));
    459 		thing = NULL;
    460 		break;
    461 	}
    462 
    463 	case PIOCGETU:		/* read u-area */
    464 	{
    465 		user_t *userp = thing;
    466 
    467 		up = PTOU(p);
    468 		*userp = *up;
    469 		prunlock(pnp);
    470 		if (copyout(userp, cmaddr, sizeof (user_t)))
    471 			error = EFAULT;
    472 		kmem_free(userp, sizeof (user_t));
    473 		thing = NULL;
    474 		break;
    475 	}
    476 
    477 	case PIOCOPENM:		/* open mapped object for reading */
    478 		error = propenm(pnp, cmaddr, un.va, rvalp, cr);
    479 		/* propenm() called prunlock(pnp) */
    480 		break;
    481 
    482 	case PIOCSTOP:		/* stop process or lwp from running */
    483 	case PIOCWSTOP:		/* wait for process or lwp to stop */
    484 		/*
    485 		 * Can't apply to a system process.
    486 		 */
    487 		if ((p->p_flag & SSYS) || p->p_as == &kas) {
    488 			prunlock(pnp);
    489 			error = EBUSY;
    490 			break;
    491 		}
    492 
    493 		if (cmd == PIOCSTOP)
    494 			pr_stop(pnp);
    495 
    496 		/*
    497 		 * If an lwp is waiting for itself or its process, don't wait.
    498 		 * The stopped lwp would never see the fact that it is stopped.
    499 		 */
    500 		if ((pnp->pr_type == PR_LWPIDFILE)?
    501 		    (pcp->prc_thread == curthread) : (p == curproc)) {
    502 			if (cmd == PIOCWSTOP)
    503 				error = EBUSY;
    504 			prunlock(pnp);
    505 			break;
    506 		}
    507 
    508 		if ((error = pr_wait_stop(pnp, (time_t)0)) != 0)
    509 			break;	/* pr_wait_stop() unlocked the process */
    510 
    511 		if (cmaddr == NULL)
    512 			prunlock(pnp);
    513 		else {
    514 			/*
    515 			 * Return process/lwp status information.
    516 			 */
    517 			t = pr_thread(pnp);	/* returns locked thread */
    518 			thread_unlock(t);
    519 			oprgetstatus(t, &un.prstat, VTOZONE(vp));
    520 			prunlock(pnp);
    521 			if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
    522 				error = EFAULT;
    523 		}
    524 		break;
    525 
    526 	case PIOCRUN:		/* make lwp or process runnable */
    527 	{
    528 		long flags = un.prrun.pr_flags;
    529 
    530 		/*
    531 		 * Cannot set an lwp running is it is not stopped.
    532 		 * Also, no lwp other than the /proc agent lwp can
    533 		 * be set running so long as the /proc agent lwp exists.
    534 		 */
    535 		if ((!ISTOPPED(t) && !VSTOPPED(t) &&
    536 		    !(t->t_proc_flag & TP_PRSTOP)) ||
    537 		    (p->p_agenttp != NULL &&
    538 		    (t != p->p_agenttp || pnp->pr_type != PR_LWPIDFILE))) {
    539 			prunlock(pnp);
    540 			error = EBUSY;
    541 			break;
    542 		}
    543 
    544 		if (flags & (PRSHOLD|PRSTRACE|PRSFAULT|PRSVADDR))
    545 			prsetrun(t, &un.prrun);
    546 
    547 		error = pr_setrun(pnp, prmaprunflags(flags));
    548 
    549 		prunlock(pnp);
    550 		break;
    551 	}
    552 
    553 	case PIOCLWPIDS:	/* get array of lwp identifiers */
    554 	{
    555 		int nlwp;
    556 		int Nlwp;
    557 		id_t *idp;
    558 		id_t *Bidp;
    559 
    560 		Nlwp = nlwp = p->p_lwpcnt;
    561 
    562 		if (thing && thingsize != (Nlwp+1) * sizeof (id_t)) {
    563 			kmem_free(thing, thingsize);
    564 			thing = NULL;
    565 		}
    566 		if (thing == NULL) {
    567 			thingsize = (Nlwp+1) * sizeof (id_t);
    568 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
    569 		}
    570 		if (thing == NULL) {
    571 			prunlock(pnp);
    572 			goto startover;
    573 		}
    574 
    575 		idp = thing;
    576 		thing = NULL;
    577 		Bidp = idp;
    578 		if ((t = p->p_tlist) != NULL) {
    579 			do {
    580 				ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
    581 				ASSERT(nlwp > 0);
    582 				--nlwp;
    583 				*idp++ = t->t_tid;
    584 			} while ((t = t->t_forw) != p->p_tlist);
    585 		}
    586 		*idp = 0;
    587 		ASSERT(nlwp == 0);
    588 		prunlock(pnp);
    589 		if (copyout(Bidp, cmaddr, (Nlwp+1) * sizeof (id_t)))
    590 			error = EFAULT;
    591 		kmem_free(Bidp, (Nlwp+1) * sizeof (id_t));
    592 		break;
    593 	}
    594 
    595 	case PIOCOPENLWP:	/* return /proc lwp file descriptor */
    596 	{
    597 		vnode_t *xvp;
    598 		int n;
    599 
    600 		prunlock(pnp);
    601 		if ((xvp = prlwpnode(pnp, un.lwpid)) == NULL)
    602 			error = ENOENT;
    603 		else if (error = fassign(&xvp, flag & (FREAD|FWRITE), &n)) {
    604 			VN_RELE(xvp);
    605 		} else
    606 			*rvalp = n;
    607 		break;
    608 	}
    609 
    610 	case PIOCOPENPD:	/* return /proc page data file descriptor */
    611 	{
    612 		vnode_t *xvp = PTOV(xpnp);
    613 		vnode_t *dp = pnp->pr_parent;
    614 		int n;
    615 
    616 		if (pnp->pr_type == PR_LWPIDFILE) {
    617 			dp = VTOP(dp)->pr_parent;
    618 			dp = VTOP(dp)->pr_parent;
    619 		}
    620 		ASSERT(VTOP(dp)->pr_type == PR_PIDDIR);
    621 
    622 		VN_HOLD(dp);
    623 		pcp = pnp->pr_pcommon;
    624 		xpnp->pr_ino = ptoi(pcp->prc_pid);
    625 		xpnp->pr_common = pcp;
    626 		xpnp->pr_pcommon = pcp;
    627 		xpnp->pr_parent = dp;
    628 
    629 		xpnp->pr_next = p->p_plist;
    630 		p->p_plist = xvp;
    631 
    632 		prunlock(pnp);
    633 		if (error = fassign(&xvp, FREAD, &n)) {
    634 			VN_RELE(xvp);
    635 		} else
    636 			*rvalp = n;
    637 
    638 		xpnp = NULL;
    639 		break;
    640 	}
    641 
    642 	case PIOCGTRACE:	/* get signal trace mask */
    643 		prassignset(&un.smask, &p->p_sigmask);
    644 		prunlock(pnp);
    645 		if (copyout(&un.smask, cmaddr, sizeof (un.smask)))
    646 			error = EFAULT;
    647 		break;
    648 
    649 	case PIOCSTRACE:	/* set signal trace mask */
    650 		prdelset(&un.smask, SIGKILL);
    651 		prassignset(&p->p_sigmask, &un.smask);
    652 		if (!sigisempty(&p->p_sigmask))
    653 			p->p_proc_flag |= P_PR_TRACE;
    654 		else if (prisempty(&p->p_fltmask)) {
    655 			up = PTOU(p);
    656 			if (up->u_systrap == 0)
    657 				p->p_proc_flag &= ~P_PR_TRACE;
    658 		}
    659 		prunlock(pnp);
    660 		break;
    661 
    662 	case PIOCSSIG:		/* set current signal */
    663 		error = pr_setsig(pnp, &un.info);
    664 		prunlock(pnp);
    665 		if (un.info.si_signo == SIGKILL && error == 0)
    666 			pr_wait_die(pnp);
    667 		break;
    668 
    669 	case PIOCKILL:		/* send signal */
    670 	{
    671 		int sig = (int)un.signo;
    672 
    673 		error = pr_kill(pnp, sig, cr);
    674 		prunlock(pnp);
    675 		if (sig == SIGKILL && error == 0)
    676 			pr_wait_die(pnp);
    677 		break;
    678 	}
    679 
    680 	case PIOCUNKILL:	/* delete a signal */
    681 		error = pr_unkill(pnp, (int)un.signo);
    682 		prunlock(pnp);
    683 		break;
    684 
    685 	case PIOCNICE:		/* set nice priority */
    686 		error = pr_nice(p, (int)un.nice, cr);
    687 		prunlock(pnp);
    688 		break;
    689 
    690 	case PIOCGENTRY:	/* get syscall entry bit mask */
    691 	case PIOCGEXIT:		/* get syscall exit bit mask */
    692 		up = PTOU(p);
    693 		if (cmd == PIOCGENTRY) {
    694 			prassignset(&un.prmask, &up->u_entrymask);
    695 		} else {
    696 			prassignset(&un.prmask, &up->u_exitmask);
    697 		}
    698 		prunlock(pnp);
    699 		if (copyout(&un.prmask, cmaddr, sizeof (un.prmask)))
    700 			error = EFAULT;
    701 		break;
    702 
    703 	case PIOCSENTRY:	/* set syscall entry bit mask */
    704 	case PIOCSEXIT:		/* set syscall exit bit mask */
    705 		pr_setentryexit(p, &un.prmask, cmd == PIOCSENTRY);
    706 		prunlock(pnp);
    707 		break;
    708 
    709 	case PIOCSRLC:		/* obsolete: set running on last /proc close */
    710 		error = pr_set(p, prmapsetflags(PR_RLC));
    711 		prunlock(pnp);
    712 		break;
    713 
    714 	case PIOCRRLC:		/* obsolete: reset run-on-last-close flag */
    715 		error = pr_unset(p, prmapsetflags(PR_RLC));
    716 		prunlock(pnp);
    717 		break;
    718 
    719 	case PIOCSFORK:		/* obsolete: set inherit-on-fork flag */
    720 		error = pr_set(p, prmapsetflags(PR_FORK));
    721 		prunlock(pnp);
    722 		break;
    723 
    724 	case PIOCRFORK:		/* obsolete: reset inherit-on-fork flag */
    725 		error = pr_unset(p, prmapsetflags(PR_FORK));
    726 		prunlock(pnp);
    727 		break;
    728 
    729 	case PIOCSET:		/* set process flags */
    730 		error = pr_set(p, prmapsetflags(un.flags));
    731 		prunlock(pnp);
    732 		break;
    733 
    734 	case PIOCRESET:		/* reset process flags */
    735 		error = pr_unset(p, prmapsetflags(un.flags));
    736 		prunlock(pnp);
    737 		break;
    738 
    739 	case PIOCGREG:		/* get general registers */
    740 		if (t->t_state != TS_STOPPED && !VSTOPPED(t))
    741 			bzero(un.regs, sizeof (un.regs));
    742 		else {
    743 			/* drop p_lock while touching the lwp's stack */
    744 			mutex_exit(&p->p_lock);
    745 			prgetprregs(lwp, un.regs);
    746 			mutex_enter(&p->p_lock);
    747 		}
    748 		prunlock(pnp);
    749 		if (copyout(un.regs, cmaddr, sizeof (un.regs)))
    750 			error = EFAULT;
    751 		break;
    752 
    753 	case PIOCSREG:		/* set general registers */
    754 		if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
    755 			error = EBUSY;
    756 		else {
    757 			/* drop p_lock while touching the lwp's stack */
    758 			mutex_exit(&p->p_lock);
    759 			prsetprregs(lwp, un.regs, 0);
    760 			mutex_enter(&p->p_lock);
    761 		}
    762 		prunlock(pnp);
    763 		break;
    764 
    765 	case PIOCGFPREG:	/* get floating-point registers */
    766 		if (!prhasfp()) {
    767 			prunlock(pnp);
    768 			error = EINVAL;	/* No FP support */
    769 			break;
    770 		}
    771 
    772 		if (t->t_state != TS_STOPPED && !VSTOPPED(t))
    773 			bzero(&un.fpregs, sizeof (un.fpregs));
    774 		else {
    775 			/* drop p_lock while touching the lwp's stack */
    776 			mutex_exit(&p->p_lock);
    777 			prgetprfpregs(lwp, &un.fpregs);
    778 			mutex_enter(&p->p_lock);
    779 		}
    780 		prunlock(pnp);
    781 		if (copyout(&un.fpregs, cmaddr, sizeof (un.fpregs)))
    782 			error = EFAULT;
    783 		break;
    784 
    785 	case PIOCSFPREG:	/* set floating-point registers */
    786 		if (!prhasfp())
    787 			error = EINVAL;	/* No FP support */
    788 		else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
    789 			error = EBUSY;
    790 		else {
    791 			/* drop p_lock while touching the lwp's stack */
    792 			mutex_exit(&p->p_lock);
    793 			prsetprfpregs(lwp, &un.fpregs);
    794 			mutex_enter(&p->p_lock);
    795 		}
    796 		prunlock(pnp);
    797 		break;
    798 
    799 	case PIOCGXREGSIZE:	/* get the size of the extra registers */
    800 	{
    801 		int xregsize;
    802 
    803 		if (prhasx(p)) {
    804 			xregsize = prgetprxregsize(p);
    805 			prunlock(pnp);
    806 			if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
    807 				error = EFAULT;
    808 		} else {
    809 			prunlock(pnp);
    810 			error = EINVAL;	/* No extra register support */
    811 		}
    812 		break;
    813 	}
    814 
    815 	case PIOCGXREG:		/* get extra registers */
    816 		if (prhasx(p)) {
    817 			bzero(thing, thingsize);
    818 			if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
    819 				/* drop p_lock to touch the stack */
    820 				mutex_exit(&p->p_lock);
    821 				prgetprxregs(lwp, thing);
    822 				mutex_enter(&p->p_lock);
    823 			}
    824 			prunlock(pnp);
    825 			if (copyout(thing, cmaddr, thingsize))
    826 				error = EFAULT;
    827 		} else {
    828 			prunlock(pnp);
    829 			error = EINVAL;	/* No extra register support */
    830 		}
    831 		if (thing) {
    832 			kmem_free(thing, thingsize);
    833 			thing = NULL;
    834 		}
    835 		break;
    836 
    837 	case PIOCSXREG:		/* set extra registers */
    838 		if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
    839 			error = EBUSY;
    840 		else if (!prhasx(p))
    841 			error = EINVAL;	/* No extra register support */
    842 		else if (thing) {
    843 			/* drop p_lock while touching the lwp's stack */
    844 			mutex_exit(&p->p_lock);
    845 			prsetprxregs(lwp, thing);
    846 			mutex_enter(&p->p_lock);
    847 		}
    848 		prunlock(pnp);
    849 		if (thing) {
    850 			kmem_free(thing, thingsize);
    851 			thing = NULL;
    852 		}
    853 		break;
    854 
    855 	case PIOCSTATUS:	/* get process/lwp status */
    856 		oprgetstatus(t, &un.prstat, VTOZONE(vp));
    857 		prunlock(pnp);
    858 		if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
    859 			error = EFAULT;
    860 		break;
    861 
    862 	case PIOCLSTATUS:	/* get status for process & all lwps */
    863 	{
    864 		int Nlwp;
    865 		int nlwp;
    866 		prstatus_t *Bprsp;
    867 		prstatus_t *prsp;
    868 
    869 		nlwp = Nlwp = p->p_lwpcnt;
    870 
    871 		if (thing && thingsize != (Nlwp+1) * sizeof (prstatus_t)) {
    872 			kmem_free(thing, thingsize);
    873 			thing = NULL;
    874 		}
    875 		if (thing == NULL) {
    876 			thingsize = (Nlwp+1) * sizeof (prstatus_t);
    877 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
    878 		}
    879 		if (thing == NULL) {
    880 			prunlock(pnp);
    881 			goto startover;
    882 		}
    883 
    884 		Bprsp = thing;
    885 		thing = NULL;
    886 		prsp = Bprsp;
    887 		oprgetstatus(t, prsp, VTOZONE(vp));
    888 		t = p->p_tlist;
    889 		do {
    890 			ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
    891 			ASSERT(nlwp > 0);
    892 			--nlwp;
    893 			oprgetstatus(t, ++prsp, VTOZONE(vp));
    894 		} while ((t = t->t_forw) != p->p_tlist);
    895 		ASSERT(nlwp == 0);
    896 		prunlock(pnp);
    897 		if (copyout(Bprsp, cmaddr, (Nlwp+1) * sizeof (prstatus_t)))
    898 			error = EFAULT;
    899 
    900 		kmem_free(Bprsp, (Nlwp+1) * sizeof (prstatus_t));
    901 		break;
    902 	}
    903 
    904 	case PIOCPSINFO:	/* get ps(1) information */
    905 	{
    906 		prpsinfo_t *psp = &un.prps;
    907 
    908 		oprgetpsinfo(p, psp,
    909 		    (pnp->pr_type == PR_LWPIDFILE)? pcp->prc_thread : NULL);
    910 
    911 		prunlock(pnp);
    912 		if (copyout(&un.prps, cmaddr, sizeof (un.prps)))
    913 			error = EFAULT;
    914 		break;
    915 	}
    916 
    917 	case PIOCMAXSIG:	/* get maximum signal number */
    918 	{
    919 		int n = nsig-1;
    920 
    921 		prunlock(pnp);
    922 		if (copyout(&n, cmaddr, sizeof (n)))
    923 			error = EFAULT;
    924 		break;
    925 	}
    926 
    927 	case PIOCACTION:	/* get signal action structures */
    928 	{
    929 		uint_t sig;
    930 		struct sigaction *sap = thing;
    931 
    932 		up = PTOU(p);
    933 		for (sig = 1; sig < nsig; sig++)
    934 			prgetaction(p, up, sig, &sap[sig-1]);
    935 		prunlock(pnp);
    936 		if (copyout(sap, cmaddr, (nsig-1) * sizeof (struct sigaction)))
    937 			error = EFAULT;
    938 		kmem_free(sap, (nsig-1) * sizeof (struct sigaction));
    939 		thing = NULL;
    940 		break;
    941 	}
    942 
    943 	case PIOCGHOLD:		/* get signal-hold mask */
    944 		schedctl_finish_sigblock(t);
    945 		sigktou(&t->t_hold, &un.holdmask);
    946 		prunlock(pnp);
    947 		if (copyout(&un.holdmask, cmaddr, sizeof (un.holdmask)))
    948 			error = EFAULT;
    949 		break;
    950 
    951 	case PIOCSHOLD:		/* set signal-hold mask */
    952 		pr_sethold(pnp, &un.holdmask);
    953 		prunlock(pnp);
    954 		break;
    955 
    956 	case PIOCNMAP:		/* get number of memory mappings */
    957 	{
    958 		int n;
    959 		struct as *as = p->p_as;
    960 
    961 		if ((p->p_flag & SSYS) || as == &kas)
    962 			n = 0;
    963 		else {
    964 			mutex_exit(&p->p_lock);
    965 			AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
    966 			n = prnsegs(as, 0);
    967 			AS_LOCK_EXIT(as, &as->a_lock);
    968 			mutex_enter(&p->p_lock);
    969 		}
    970 		prunlock(pnp);
    971 		if (copyout(&n, cmaddr, sizeof (int)))
    972 			error = EFAULT;
    973 		break;
    974 	}
    975 
    976 	case PIOCMAP:		/* get memory map information */
    977 	{
    978 		list_t iolhead;
    979 		struct as *as = p->p_as;
    980 
    981 		if ((p->p_flag & SSYS) || as == &kas) {
    982 			error = 0;
    983 			prunlock(pnp);
    984 		} else {
    985 			mutex_exit(&p->p_lock);
    986 			AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
    987 			error = oprgetmap(p, &iolhead);
    988 			AS_LOCK_EXIT(as, &as->a_lock);
    989 			mutex_enter(&p->p_lock);
    990 			prunlock(pnp);
    991 
    992 			error = pr_iol_copyout_and_free(&iolhead,
    993 			    &cmaddr, error);
    994 		}
    995 		/*
    996 		 * The procfs PIOCMAP ioctl returns an all-zero buffer
    997 		 * to indicate the end of the prmap[] array.
    998 		 * Append it to whatever has already been copied out.
    999 		 */
   1000 		bzero(&un.prmap, sizeof (un.prmap));
   1001 		if (!error && copyout(&un.prmap, cmaddr, sizeof (un.prmap)))
   1002 			error = EFAULT;
   1003 
   1004 		break;
   1005 	}
   1006 
   1007 	case PIOCGFAULT:	/* get mask of traced faults */
   1008 		prassignset(&un.fltmask, &p->p_fltmask);
   1009 		prunlock(pnp);
   1010 		if (copyout(&un.fltmask, cmaddr, sizeof (un.fltmask)))
   1011 			error = EFAULT;
   1012 		break;
   1013 
   1014 	case PIOCSFAULT:	/* set mask of traced faults */
   1015 		pr_setfault(p, &un.fltmask);
   1016 		prunlock(pnp);
   1017 		break;
   1018 
   1019 	case PIOCCFAULT:	/* clear current fault */
   1020 		lwp->lwp_curflt = 0;
   1021 		prunlock(pnp);
   1022 		break;
   1023 
   1024 	case PIOCCRED:		/* get process credentials */
   1025 	{
   1026 		cred_t *cp;
   1027 
   1028 		mutex_enter(&p->p_crlock);
   1029 		cp = p->p_cred;
   1030 		un.prcred.pr_euid = crgetuid(cp);
   1031 		un.prcred.pr_ruid = crgetruid(cp);
   1032 		un.prcred.pr_suid = crgetsuid(cp);
   1033 		un.prcred.pr_egid = crgetgid(cp);
   1034 		un.prcred.pr_rgid = crgetrgid(cp);
   1035 		un.prcred.pr_sgid = crgetsgid(cp);
   1036 		un.prcred.pr_ngroups = crgetngroups(cp);
   1037 		mutex_exit(&p->p_crlock);
   1038 
   1039 		prunlock(pnp);
   1040 		if (copyout(&un.prcred, cmaddr, sizeof (un.prcred)))
   1041 			error = EFAULT;
   1042 		break;
   1043 	}
   1044 
   1045 	case PIOCGROUPS:	/* get supplementary groups */
   1046 	{
   1047 		cred_t *cp;
   1048 
   1049 		mutex_enter(&p->p_crlock);
   1050 		cp = p->p_cred;
   1051 		crhold(cp);
   1052 		mutex_exit(&p->p_crlock);
   1053 
   1054 		prunlock(pnp);
   1055 		if (copyout(crgetgroups(cp), cmaddr,
   1056 		    MAX(crgetngroups(cp), 1) * sizeof (gid_t)))
   1057 			error = EFAULT;
   1058 		crfree(cp);
   1059 		break;
   1060 	}
   1061 
   1062 	case PIOCUSAGE:		/* get usage info */
   1063 	{
   1064 		/*
   1065 		 * For an lwp file descriptor, return just the lwp usage.
   1066 		 * For a process file descriptor, return total usage,
   1067 		 * all current lwps plus all defunct lwps.
   1068 		 */
   1069 		prhusage_t *pup = &un.prhusage;
   1070 		prusage_t *upup;
   1071 
   1072 		bzero(pup, sizeof (*pup));
   1073 		pup->pr_tstamp = gethrtime();
   1074 
   1075 		if (pnp->pr_type == PR_LWPIDFILE) {
   1076 			t = pcp->prc_thread;
   1077 			if (t != NULL)
   1078 				prgetusage(t, pup);
   1079 			else
   1080 				error = ENOENT;
   1081 		} else {
   1082 			pup->pr_count  = p->p_defunct;
   1083 			pup->pr_create = p->p_mstart;
   1084 			pup->pr_term   = p->p_mterm;
   1085 
   1086 			pup->pr_rtime    = p->p_mlreal;
   1087 			pup->pr_utime    = p->p_acct[LMS_USER];
   1088 			pup->pr_stime    = p->p_acct[LMS_SYSTEM];
   1089 			pup->pr_ttime    = p->p_acct[LMS_TRAP];
   1090 			pup->pr_tftime   = p->p_acct[LMS_TFAULT];
   1091 			pup->pr_dftime   = p->p_acct[LMS_DFAULT];
   1092 			pup->pr_kftime   = p->p_acct[LMS_KFAULT];
   1093 			pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
   1094 			pup->pr_slptime  = p->p_acct[LMS_SLEEP];
   1095 			pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
   1096 			pup->pr_stoptime = p->p_acct[LMS_STOPPED];
   1097 
   1098 			pup->pr_minf  = p->p_ru.minflt;
   1099 			pup->pr_majf  = p->p_ru.majflt;
   1100 			pup->pr_nswap = p->p_ru.nswap;
   1101 			pup->pr_inblk = p->p_ru.inblock;
   1102 			pup->pr_oublk = p->p_ru.oublock;
   1103 			pup->pr_msnd  = p->p_ru.msgsnd;
   1104 			pup->pr_mrcv  = p->p_ru.msgrcv;
   1105 			pup->pr_sigs  = p->p_ru.nsignals;
   1106 			pup->pr_vctx  = p->p_ru.nvcsw;
   1107 			pup->pr_ictx  = p->p_ru.nivcsw;
   1108 			pup->pr_sysc  = p->p_ru.sysc;
   1109 			pup->pr_ioch  = p->p_ru.ioch;
   1110 
   1111 			/*
   1112 			 * Add the usage information for each active lwp.
   1113 			 */
   1114 			if ((t = p->p_tlist) != NULL &&
   1115 			    !(pcp->prc_flags & PRC_DESTROY)) {
   1116 				do {
   1117 					ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
   1118 					pup->pr_count++;
   1119 					praddusage(t, pup);
   1120 				} while ((t = t->t_forw) != p->p_tlist);
   1121 			}
   1122 		}
   1123 
   1124 		prunlock(pnp);
   1125 
   1126 		upup = kmem_zalloc(sizeof (*upup), KM_SLEEP);
   1127 		prcvtusage(&un.prhusage, upup);
   1128 		if (copyout(upup, cmaddr, sizeof (*upup)))
   1129 			error = EFAULT;
   1130 		kmem_free(upup, sizeof (*upup));
   1131 
   1132 		break;
   1133 	}
   1134 
   1135 	case PIOCLUSAGE:	/* get detailed usage info */
   1136 	{
   1137 		int Nlwp;
   1138 		int nlwp;
   1139 		prusage_t *upup;
   1140 		prusage_t *Bupup;
   1141 		prhusage_t *pup;
   1142 		hrtime_t curtime;
   1143 
   1144 		nlwp = Nlwp = (pcp->prc_flags & PRC_DESTROY)? 0 : p->p_lwpcnt;
   1145 
   1146 		if (thing && thingsize !=
   1147 		    sizeof (prhusage_t) + (Nlwp+1) * sizeof (prusage_t)) {
   1148 			kmem_free(thing, thingsize);
   1149 			thing = NULL;
   1150 		}
   1151 		if (thing == NULL) {
   1152 			thingsize = sizeof (prhusage_t) +
   1153 			    (Nlwp+1) * sizeof (prusage_t);
   1154 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
   1155 		}
   1156 		if (thing == NULL) {
   1157 			prunlock(pnp);
   1158 			goto startover;
   1159 		}
   1160 
   1161 		pup = thing;
   1162 		upup = Bupup = (prusage_t *)(pup + 1);
   1163 
   1164 		ASSERT(p == pcp->prc_proc);
   1165 
   1166 		curtime = gethrtime();
   1167 
   1168 		/*
   1169 		 * First the summation over defunct lwps.
   1170 		 */
   1171 		bzero(pup, sizeof (*pup));
   1172 		pup->pr_count  = p->p_defunct;
   1173 		pup->pr_tstamp = curtime;
   1174 		pup->pr_create = p->p_mstart;
   1175 		pup->pr_term   = p->p_mterm;
   1176 
   1177 		pup->pr_rtime    = p->p_mlreal;
   1178 		pup->pr_utime    = p->p_acct[LMS_USER];
   1179 		pup->pr_stime    = p->p_acct[LMS_SYSTEM];
   1180 		pup->pr_ttime    = p->p_acct[LMS_TRAP];
   1181 		pup->pr_tftime   = p->p_acct[LMS_TFAULT];
   1182 		pup->pr_dftime   = p->p_acct[LMS_DFAULT];
   1183 		pup->pr_kftime   = p->p_acct[LMS_KFAULT];
   1184 		pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
   1185 		pup->pr_slptime  = p->p_acct[LMS_SLEEP];
   1186 		pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
   1187 		pup->pr_stoptime = p->p_acct[LMS_STOPPED];
   1188 
   1189 		pup->pr_minf  = p->p_ru.minflt;
   1190 		pup->pr_majf  = p->p_ru.majflt;
   1191 		pup->pr_nswap = p->p_ru.nswap;
   1192 		pup->pr_inblk = p->p_ru.inblock;
   1193 		pup->pr_oublk = p->p_ru.oublock;
   1194 		pup->pr_msnd  = p->p_ru.msgsnd;
   1195 		pup->pr_mrcv  = p->p_ru.msgrcv;
   1196 		pup->pr_sigs  = p->p_ru.nsignals;
   1197 		pup->pr_vctx  = p->p_ru.nvcsw;
   1198 		pup->pr_ictx  = p->p_ru.nivcsw;
   1199 		pup->pr_sysc  = p->p_ru.sysc;
   1200 		pup->pr_ioch  = p->p_ru.ioch;
   1201 
   1202 		prcvtusage(pup, upup);
   1203 
   1204 		/*
   1205 		 * Fill one prusage struct for each active lwp.
   1206 		 */
   1207 		if ((t = p->p_tlist) != NULL &&
   1208 		    !(pcp->prc_flags & PRC_DESTROY)) {
   1209 			do {
   1210 				ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
   1211 				ASSERT(nlwp > 0);
   1212 				--nlwp;
   1213 				upup++;
   1214 				prgetusage(t, pup);
   1215 				prcvtusage(pup, upup);
   1216 			} while ((t = t->t_forw) != p->p_tlist);
   1217 		}
   1218 		ASSERT(nlwp == 0);
   1219 
   1220 		prunlock(pnp);
   1221 		if (copyout(Bupup, cmaddr, (Nlwp+1) * sizeof (prusage_t)))
   1222 			error = EFAULT;
   1223 		kmem_free(thing, thingsize);
   1224 		thing = NULL;
   1225 		break;
   1226 	}
   1227 
   1228 	case PIOCNAUXV:		/* get number of aux vector entries */
   1229 	{
   1230 		int n = __KERN_NAUXV_IMPL;
   1231 
   1232 		prunlock(pnp);
   1233 		if (copyout(&n, cmaddr, sizeof (int)))
   1234 			error = EFAULT;
   1235 		break;
   1236 	}
   1237 
   1238 	case PIOCAUXV:		/* get aux vector (see sys/auxv.h) */
   1239 	{
   1240 		up = PTOU(p);
   1241 		bcopy(up->u_auxv, un.auxv,
   1242 		    __KERN_NAUXV_IMPL * sizeof (auxv_t));
   1243 		prunlock(pnp);
   1244 		if (copyout(un.auxv, cmaddr,
   1245 		    __KERN_NAUXV_IMPL * sizeof (auxv_t)))
   1246 			error = EFAULT;
   1247 		break;
   1248 	}
   1249 
   1250 #if defined(__i386) || defined(__amd64)
   1251 	case PIOCNLDT:		/* get number of LDT entries */
   1252 	{
   1253 		int n;
   1254 
   1255 		mutex_exit(&p->p_lock);
   1256 		mutex_enter(&p->p_ldtlock);
   1257 		n = prnldt(p);
   1258 		mutex_exit(&p->p_ldtlock);
   1259 		mutex_enter(&p->p_lock);
   1260 		prunlock(pnp);
   1261 		if (copyout(&n, cmaddr, sizeof (n)))
   1262 			error = EFAULT;
   1263 		break;
   1264 	}
   1265 
   1266 	case PIOCLDT:		/* get LDT entries */
   1267 	{
   1268 		struct ssd *ssd;
   1269 		int n;
   1270 
   1271 		mutex_exit(&p->p_lock);
   1272 		mutex_enter(&p->p_ldtlock);
   1273 		n = prnldt(p);
   1274 
   1275 		if (thing && thingsize != (n+1) * sizeof (*ssd)) {
   1276 			kmem_free(thing, thingsize);
   1277 			thing = NULL;
   1278 		}
   1279 		if (thing == NULL) {
   1280 			thingsize = (n+1) * sizeof (*ssd);
   1281 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
   1282 		}
   1283 		if (thing == NULL) {
   1284 			mutex_exit(&p->p_ldtlock);
   1285 			mutex_enter(&p->p_lock);
   1286 			prunlock(pnp);
   1287 			goto startover;
   1288 		}
   1289 
   1290 		ssd = thing;
   1291 		thing = NULL;
   1292 		if (n != 0)
   1293 			prgetldt(p, ssd);
   1294 		mutex_exit(&p->p_ldtlock);
   1295 		mutex_enter(&p->p_lock);
   1296 		prunlock(pnp);
   1297 
   1298 		/* mark the end of the list with a null entry */
   1299 		bzero(&ssd[n], sizeof (*ssd));
   1300 		if (copyout(ssd, cmaddr, (n+1) * sizeof (*ssd)))
   1301 			error = EFAULT;
   1302 		kmem_free(ssd, (n+1) * sizeof (*ssd));
   1303 		break;
   1304 	}
   1305 #endif	/* __i386 || __amd64 */
   1306 
   1307 #if defined(__sparc)
   1308 	case PIOCGWIN:		/* get gwindows_t (see sys/reg.h) */
   1309 	{
   1310 		gwindows_t *gwp = thing;
   1311 
   1312 		/* drop p->p_lock while touching the stack */
   1313 		mutex_exit(&p->p_lock);
   1314 		bzero(gwp, sizeof (*gwp));
   1315 		prgetwindows(lwp, gwp);
   1316 		mutex_enter(&p->p_lock);
   1317 		prunlock(pnp);
   1318 		if (copyout(gwp, cmaddr, sizeof (*gwp)))
   1319 			error = EFAULT;
   1320 		kmem_free(gwp, sizeof (gwindows_t));
   1321 		thing = NULL;
   1322 		break;
   1323 	}
   1324 #endif	/* __sparc */
   1325 
   1326 	default:
   1327 		prunlock(pnp);
   1328 		error = EINVAL;
   1329 		break;
   1330 
   1331 	}
   1332 
   1333 	ASSERT(thing == NULL);
   1334 	ASSERT(xpnp == NULL);
   1335 	return (error);
   1336 }
   1337 
   1338 #ifdef _SYSCALL32_IMPL
   1339 
   1340 static int oprgetmap32(proc_t *, list_t *);
   1341 
   1342 void
   1343 oprgetstatus32(kthread_t *t, prstatus32_t *sp, zone_t *zp)
   1344 {
   1345 	proc_t *p = ttoproc(t);
   1346 	klwp_t *lwp = ttolwp(t);
   1347 	int32_t flags;
   1348 	user_t *up;
   1349 	ulong_t instr;
   1350 
   1351 	ASSERT(MUTEX_HELD(&p->p_lock));
   1352 
   1353 	up = PTOU(p);
   1354 	bzero(sp, sizeof (*sp));
   1355 	flags = 0L;
   1356 	if (t->t_state == TS_STOPPED) {
   1357 		flags |= PR_STOPPED;
   1358 		if ((t->t_schedflag & TS_PSTART) == 0)
   1359 			flags |= PR_ISTOP;
   1360 	} else if (VSTOPPED(t)) {
   1361 		flags |= PR_STOPPED|PR_ISTOP;
   1362 	}
   1363 	if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
   1364 		flags |= PR_DSTOP;
   1365 	if (lwp->lwp_asleep)
   1366 		flags |= PR_ASLEEP;
   1367 	if (p->p_proc_flag & P_PR_FORK)
   1368 		flags |= PR_FORK;
   1369 	if (p->p_proc_flag & P_PR_RUNLCL)
   1370 		flags |= PR_RLC;
   1371 	if (p->p_proc_flag & P_PR_KILLCL)
   1372 		flags |= PR_KLC;
   1373 	if (p->p_proc_flag & P_PR_ASYNC)
   1374 		flags |= PR_ASYNC;
   1375 	if (p->p_proc_flag & P_PR_BPTADJ)
   1376 		flags |= PR_BPTADJ;
   1377 	if (p->p_proc_flag & P_PR_PTRACE)
   1378 		flags |= PR_PCOMPAT;
   1379 	if (t->t_proc_flag & TP_MSACCT)
   1380 		flags |= PR_MSACCT;
   1381 	sp->pr_flags = flags;
   1382 	if (VSTOPPED(t)) {
   1383 		sp->pr_why   = PR_REQUESTED;
   1384 		sp->pr_what  = 0;
   1385 	} else {
   1386 		sp->pr_why   = t->t_whystop;
   1387 		sp->pr_what  = t->t_whatstop;
   1388 	}
   1389 
   1390 	if (t->t_whystop == PR_FAULTED) {
   1391 		siginfo_kto32(&lwp->lwp_siginfo, &sp->pr_info);
   1392 		if (t->t_whatstop == FLTPAGE)
   1393 			sp->pr_info.si_addr =
   1394 			    (caddr32_t)(uintptr_t)lwp->lwp_siginfo.si_addr;
   1395 	} else if (lwp->lwp_curinfo)
   1396 		siginfo_kto32(&lwp->lwp_curinfo->sq_info, &sp->pr_info);
   1397 
   1398 	if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
   1399 	    sp->pr_info.si_zoneid != zp->zone_id) {
   1400 		sp->pr_info.si_pid = zp->zone_zsched->p_pid;
   1401 		sp->pr_info.si_uid = 0;
   1402 		sp->pr_info.si_ctid = -1;
   1403 		sp->pr_info.si_zoneid = zp->zone_id;
   1404 	}
   1405 
   1406 	sp->pr_cursig  = lwp->lwp_cursig;
   1407 	prassignset(&sp->pr_sigpend, &p->p_sig);
   1408 	prassignset(&sp->pr_lwppend, &t->t_sig);
   1409 	schedctl_finish_sigblock(t);
   1410 	prassignset(&sp->pr_sighold, &t->t_hold);
   1411 	sp->pr_altstack.ss_sp =
   1412 	    (caddr32_t)(uintptr_t)lwp->lwp_sigaltstack.ss_sp;
   1413 	sp->pr_altstack.ss_size = (size32_t)lwp->lwp_sigaltstack.ss_size;
   1414 	sp->pr_altstack.ss_flags = (int32_t)lwp->lwp_sigaltstack.ss_flags;
   1415 	prgetaction32(p, up, lwp->lwp_cursig, &sp->pr_action);
   1416 	sp->pr_pid   = p->p_pid;
   1417 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
   1418 	    (p->p_flag & SZONETOP)) {
   1419 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
   1420 		/*
   1421 		 * Inside local zones, fake zsched's pid as parent pids for
   1422 		 * processes which reference processes outside of the zone.
   1423 		 */
   1424 		sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
   1425 	} else {
   1426 		sp->pr_ppid = p->p_ppid;
   1427 	}
   1428 	sp->pr_pgrp  = p->p_pgrp;
   1429 	sp->pr_sid   = p->p_sessp->s_sid;
   1430 	hrt2ts32(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
   1431 	hrt2ts32(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
   1432 	TICK_TO_TIMESTRUC32(p->p_cutime, &sp->pr_cutime);
   1433 	TICK_TO_TIMESTRUC32(p->p_cstime, &sp->pr_cstime);
   1434 	(void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
   1435 	    sizeof (sp->pr_clname) - 1);
   1436 	sp->pr_who = t->t_tid;
   1437 	sp->pr_nlwp = p->p_lwpcnt;
   1438 	sp->pr_brkbase = (caddr32_t)(uintptr_t)p->p_brkbase;
   1439 	sp->pr_brksize = (size32_t)p->p_brksize;
   1440 	sp->pr_stkbase = (caddr32_t)(uintptr_t)prgetstackbase(p);
   1441 	sp->pr_stksize = (size32_t)p->p_stksize;
   1442 	sp->pr_oldcontext = (caddr32_t)lwp->lwp_oldcontext;
   1443 	sp->pr_processor = t->t_cpu->cpu_id;
   1444 	sp->pr_bind = t->t_bind_cpu;
   1445 
   1446 	/*
   1447 	 * Fetch the current instruction, if not a system process.
   1448 	 * We don't attempt this unless the lwp is stopped.
   1449 	 */
   1450 	if ((p->p_flag & SSYS) || p->p_as == &kas)
   1451 		sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
   1452 	else if (!(flags & PR_STOPPED))
   1453 		sp->pr_flags |= PR_PCINVAL;
   1454 	else if (!prfetchinstr(lwp, &instr))
   1455 		sp->pr_flags |= PR_PCINVAL;
   1456 	else
   1457 		sp->pr_instr = (uint32_t)instr;
   1458 
   1459 	/*
   1460 	 * Drop p_lock while touching the lwp's stack.
   1461 	 */
   1462 	mutex_exit(&p->p_lock);
   1463 	if (prisstep(lwp))
   1464 		sp->pr_flags |= PR_STEP;
   1465 	if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
   1466 		int i;
   1467 		auxv_t *auxp;
   1468 
   1469 		sp->pr_syscall = get_syscall32_args(lwp,
   1470 		    (int *)sp->pr_sysarg, &i);
   1471 		sp->pr_nsysarg = (short)i;
   1472 		if (t->t_whystop == PR_SYSEXIT && t->t_sysnum == SYS_execve) {
   1473 			sp->pr_sysarg[0] = 0;
   1474 			sp->pr_sysarg[1] = (caddr32_t)up->u_argv;
   1475 			sp->pr_sysarg[2] = (caddr32_t)up->u_envp;
   1476 			for (i = 0, auxp = up->u_auxv;
   1477 			    i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
   1478 			    i++, auxp++) {
   1479 				if (auxp->a_type == AT_SUN_EXECNAME) {
   1480 					sp->pr_sysarg[0] =
   1481 					    (caddr32_t)
   1482 					    (uintptr_t)auxp->a_un.a_ptr;
   1483 					break;
   1484 				}
   1485 			}
   1486 		}
   1487 	}
   1488 	if ((flags & PR_STOPPED) || t == curthread)
   1489 		prgetprregs32(lwp, sp->pr_reg);
   1490 	mutex_enter(&p->p_lock);
   1491 }
   1492 
   1493 void
   1494 oprgetpsinfo32(proc_t *p, prpsinfo32_t *psp, kthread_t *tp)
   1495 {
   1496 	kthread_t *t;
   1497 	char c, state;
   1498 	user_t *up;
   1499 	dev_t d;
   1500 	uint64_t pct;
   1501 	int retval, niceval;
   1502 	cred_t *cred;
   1503 	struct as *as;
   1504 	hrtime_t hrutime, hrstime, cur_time;
   1505 
   1506 	ASSERT(MUTEX_HELD(&p->p_lock));
   1507 
   1508 	bzero(psp, sizeof (*psp));
   1509 
   1510 	if ((t = tp) == NULL)
   1511 		t = prchoose(p);	/* returns locked thread */
   1512 	else
   1513 		thread_lock(t);
   1514 
   1515 	/* kludge: map thread state enum into process state enum */
   1516 
   1517 	if (t == NULL) {
   1518 		state = TS_ZOMB;
   1519 	} else {
   1520 		state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
   1521 		thread_unlock(t);
   1522 	}
   1523 
   1524 	switch (state) {
   1525 	case TS_SLEEP:		state = SSLEEP;		break;
   1526 	case TS_RUN:		state = SRUN;		break;
   1527 	case TS_ONPROC:		state = SONPROC;	break;
   1528 	case TS_ZOMB:		state = SZOMB;		break;
   1529 	case TS_STOPPED:	state = SSTOP;		break;
   1530 	default:		state = 0;		break;
   1531 	}
   1532 	switch (state) {
   1533 	case SSLEEP:	c = 'S';	break;
   1534 	case SRUN:	c = 'R';	break;
   1535 	case SZOMB:	c = 'Z';	break;
   1536 	case SSTOP:	c = 'T';	break;
   1537 	case SIDL:	c = 'I';	break;
   1538 	case SONPROC:	c = 'O';	break;
   1539 #ifdef SXBRK
   1540 	case SXBRK:	c = 'X';	break;
   1541 #endif
   1542 	default:	c = '?';	break;
   1543 	}
   1544 	psp->pr_state = state;
   1545 	psp->pr_sname = c;
   1546 	psp->pr_zomb = (state == SZOMB);
   1547 	/*
   1548 	 * only export SSYS and SMSACCT; everything else is off-limits to
   1549 	 * userland apps.
   1550 	 */
   1551 	psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
   1552 
   1553 	mutex_enter(&p->p_crlock);
   1554 	cred = p->p_cred;
   1555 	psp->pr_uid = crgetruid(cred);
   1556 	psp->pr_gid = crgetrgid(cred);
   1557 	psp->pr_euid = crgetuid(cred);
   1558 	psp->pr_egid = crgetgid(cred);
   1559 	mutex_exit(&p->p_crlock);
   1560 
   1561 	psp->pr_pid = p->p_pid;
   1562 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
   1563 	    (p->p_flag & SZONETOP)) {
   1564 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
   1565 		/*
   1566 		 * Inside local zones, fake zsched's pid as parent pids for
   1567 		 * processes which reference processes outside of the zone.
   1568 		 */
   1569 		psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
   1570 	} else {
   1571 		psp->pr_ppid = p->p_ppid;
   1572 	}
   1573 	psp->pr_pgrp = p->p_pgrp;
   1574 	psp->pr_sid = p->p_sessp->s_sid;
   1575 	psp->pr_addr = 0;	/* cannot represent 64-bit addr in 32 bits */
   1576 	hrutime = mstate_aggr_state(p, LMS_USER);
   1577 	hrstime = mstate_aggr_state(p, LMS_SYSTEM);
   1578 	hrt2ts32(hrutime + hrstime, &psp->pr_time);
   1579 	TICK_TO_TIMESTRUC32(p->p_cutime + p->p_cstime, &psp->pr_ctime);
   1580 	switch (p->p_model) {
   1581 	case DATAMODEL_ILP32:
   1582 		psp->pr_dmodel = PR_MODEL_ILP32;
   1583 		break;
   1584 	case DATAMODEL_LP64:
   1585 		psp->pr_dmodel = PR_MODEL_LP64;
   1586 		break;
   1587 	}
   1588 	if (state == SZOMB || t == NULL) {
   1589 		int wcode = p->p_wcode;		/* must be atomic read */
   1590 
   1591 		if (wcode)
   1592 			psp->pr_wstat = wstat(wcode, p->p_wdata);
   1593 		psp->pr_lttydev = PRNODEV32;
   1594 		psp->pr_ottydev = (o_dev_t)PRNODEV32;
   1595 		psp->pr_size = 0;
   1596 		psp->pr_rssize = 0;
   1597 		psp->pr_pctmem = 0;
   1598 	} else {
   1599 		up = PTOU(p);
   1600 		psp->pr_wchan = 0;	/* cannot represent in 32 bits */
   1601 		psp->pr_pri = t->t_pri;
   1602 		(void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
   1603 		    sizeof (psp->pr_clname) - 1);
   1604 		retval = CL_DONICE(t, NULL, 0, &niceval);
   1605 		if (retval == 0) {
   1606 			psp->pr_oldpri = v.v_maxsyspri - psp->pr_pri;
   1607 			psp->pr_nice = niceval + NZERO;
   1608 		} else {
   1609 			psp->pr_oldpri = 0;
   1610 			psp->pr_nice = 0;
   1611 		}
   1612 		d = cttydev(p);
   1613 #ifdef sun
   1614 		{
   1615 			extern dev_t rwsconsdev, rconsdev, uconsdev;
   1616 			/*
   1617 			 * If the controlling terminal is the real
   1618 			 * or workstation console device, map to what the
   1619 			 * user thinks is the console device. Handle case when
   1620 			 * rwsconsdev or rconsdev is set to NODEV for Starfire.
   1621 			 */
   1622 			if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
   1623 				d = uconsdev;
   1624 		}
   1625 #endif
   1626 		(void) cmpldev(&psp->pr_lttydev, d);
   1627 		psp->pr_ottydev = cmpdev(d);
   1628 		TIMESPEC_TO_TIMESPEC32(&psp->pr_start, &up->u_start);
   1629 		bcopy(up->u_comm, psp->pr_fname,
   1630 		    MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
   1631 		bcopy(up->u_psargs, psp->pr_psargs,
   1632 		    MIN(PRARGSZ-1, PSARGSZ));
   1633 		psp->pr_syscall = t->t_sysnum;
   1634 		psp->pr_argc = up->u_argc;
   1635 		psp->pr_argv = (caddr32_t)up->u_argv;
   1636 		psp->pr_envp = (caddr32_t)up->u_envp;
   1637 
   1638 		/* compute %cpu for the lwp or process */
   1639 		pct = 0;
   1640 		if ((t = tp) == NULL)
   1641 			t = p->p_tlist;
   1642 		cur_time = gethrtime_unscaled();
   1643 		do {
   1644 			pct += cpu_update_pct(t, cur_time);
   1645 			if (tp != NULL)		/* just do the one lwp */
   1646 				break;
   1647 		} while ((t = t->t_forw) != p->p_tlist);
   1648 
   1649 		psp->pr_pctcpu = prgetpctcpu(pct);
   1650 		psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */
   1651 		if (psp->pr_cpu > 99)
   1652 			psp->pr_cpu = 99;
   1653 
   1654 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
   1655 			psp->pr_size = 0;
   1656 			psp->pr_rssize = 0;
   1657 			psp->pr_pctmem = 0;
   1658 		} else {
   1659 			mutex_exit(&p->p_lock);
   1660 			AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
   1661 			psp->pr_size = (size32_t)btopr(as->a_resvsize);
   1662 			psp->pr_rssize = (size32_t)rm_asrss(as);
   1663 			psp->pr_pctmem = rm_pctmemory(as);
   1664 			AS_LOCK_EXIT(as, &as->a_lock);
   1665 			mutex_enter(&p->p_lock);
   1666 		}
   1667 	}
   1668 	psp->pr_bysize = (size32_t)ptob(psp->pr_size);
   1669 	psp->pr_byrssize = (size32_t)ptob(psp->pr_rssize);
   1670 
   1671 	/*
   1672 	 * If we are looking at an LP64 process, zero out
   1673 	 * the fields that cannot be represented in ILP32.
   1674 	 */
   1675 	if (p->p_model != DATAMODEL_ILP32) {
   1676 		psp->pr_size = 0;
   1677 		psp->pr_rssize = 0;
   1678 		psp->pr_bysize = 0;
   1679 		psp->pr_byrssize = 0;
   1680 		psp->pr_argv = 0;
   1681 		psp->pr_envp = 0;
   1682 	}
   1683 }
   1684 
   1685 /*ARGSUSED*/
   1686 static int
   1687 prioctl32(
   1688 	struct vnode *vp,
   1689 	int cmd,
   1690 	intptr_t arg,
   1691 	int flag,
   1692 	cred_t *cr,
   1693 	int *rvalp,
   1694 	caller_context_t *ct)
   1695 {
   1696 	int nsig = PROC_IS_BRANDED(curproc)? BROP(curproc)->b_nsig : NSIG;
   1697 	caddr_t cmaddr = (caddr_t)arg;
   1698 	proc_t *p;
   1699 	user_t *up;
   1700 	kthread_t *t;
   1701 	klwp_t *lwp;
   1702 	prnode_t *pnp = VTOP(vp);
   1703 	prcommon_t *pcp;
   1704 	prnode_t *xpnp = NULL;
   1705 	int error;
   1706 	int zdisp;
   1707 	void *thing = NULL;
   1708 	size_t thingsize = 0;
   1709 
   1710 	/*
   1711 	 * For copyin()/copyout().
   1712 	 */
   1713 	union {
   1714 		caddr32_t	va;
   1715 		int		signo;
   1716 		int		nice;
   1717 		uint_t		lwpid;
   1718 		int32_t		flags;
   1719 		prstatus32_t	prstat;
   1720 		prrun32_t	prrun;
   1721 		sigset_t	smask;
   1722 		siginfo32_t	info;
   1723 		sysset_t	prmask;
   1724 		prgregset32_t	regs;
   1725 		prfpregset32_t	fpregs;
   1726 		prpsinfo32_t	prps;
   1727 		sigset_t	holdmask;
   1728 		fltset_t	fltmask;
   1729 		prcred_t	prcred;
   1730 		prusage32_t	prusage;
   1731 		prhusage_t	prhusage;
   1732 		ioc_prmap32_t	prmap;
   1733 		auxv32_t	auxv[__KERN_NAUXV_IMPL];
   1734 	} un32;
   1735 
   1736 	/*
   1737 	 * Native objects for internal use.
   1738 	 */
   1739 	union {
   1740 		caddr_t		va;
   1741 		int		signo;
   1742 		int		nice;
   1743 		uint_t		lwpid;
   1744 		long		flags;
   1745 		prstatus_t	prstat;
   1746 		prrun_t		prrun;
   1747 		sigset_t	smask;
   1748 		siginfo_t	info;
   1749 		sysset_t	prmask;
   1750 		prgregset_t	regs;
   1751 		prpsinfo_t	prps;
   1752 		sigset_t	holdmask;
   1753 		fltset_t	fltmask;
   1754 		prcred_t	prcred;
   1755 		prusage_t	prusage;
   1756 		prhusage_t	prhusage;
   1757 		auxv_t		auxv[__KERN_NAUXV_IMPL];
   1758 	} un;
   1759 
   1760 	if (pnp->pr_type == PR_TMPL)
   1761 		return (prctioctl(pnp, cmd, arg, flag, cr));
   1762 
   1763 	/*
   1764 	 * Support for old /proc interface.
   1765 	 */
   1766 	if (pnp->pr_pidfile != NULL) {
   1767 		ASSERT(pnp->pr_type == PR_PIDDIR);
   1768 		vp = pnp->pr_pidfile;
   1769 		pnp = VTOP(vp);
   1770 		ASSERT(pnp->pr_type == PR_PIDFILE);
   1771 	}
   1772 
   1773 	if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
   1774 		return (ENOTTY);
   1775 
   1776 	/*
   1777 	 * Fail ioctls which are logically "write" requests unless
   1778 	 * the user has write permission.
   1779 	 */
   1780 	if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
   1781 		return (EBADF);
   1782 
   1783 	/*
   1784 	 * Perform any necessary copyin() operations before
   1785 	 * locking the process.  Helps avoid deadlocks and
   1786 	 * improves performance.
   1787 	 *
   1788 	 * Also, detect invalid ioctl codes here to avoid
   1789 	 * locking a process unnnecessarily.
   1790 	 *
   1791 	 * Also, prepare to allocate space that will be needed below,
   1792 	 * case by case.
   1793 	 */
   1794 	error = 0;
   1795 	switch (cmd) {
   1796 	case PIOCGETPR:
   1797 		thingsize = sizeof (proc_t);
   1798 		break;
   1799 	case PIOCGETU:
   1800 		thingsize = sizeof (user_t);
   1801 		break;
   1802 	case PIOCSTOP:
   1803 	case PIOCWSTOP:
   1804 	case PIOCLWPIDS:
   1805 	case PIOCGTRACE:
   1806 	case PIOCGENTRY:
   1807 	case PIOCGEXIT:
   1808 	case PIOCSRLC:
   1809 	case PIOCRRLC:
   1810 	case PIOCSFORK:
   1811 	case PIOCRFORK:
   1812 	case PIOCGREG:
   1813 	case PIOCGFPREG:
   1814 	case PIOCSTATUS:
   1815 	case PIOCLSTATUS:
   1816 	case PIOCPSINFO:
   1817 	case PIOCMAXSIG:
   1818 	case PIOCGXREGSIZE:
   1819 		break;
   1820 	case PIOCSXREG:		/* set extra registers */
   1821 	case PIOCGXREG:		/* get extra registers */
   1822 #if defined(__sparc)
   1823 		thingsize = sizeof (prxregset_t);
   1824 #else
   1825 		thingsize = 0;
   1826 #endif
   1827 		break;
   1828 	case PIOCACTION:
   1829 		thingsize = (nsig-1) * sizeof (struct sigaction32);
   1830 		break;
   1831 	case PIOCGHOLD:
   1832 	case PIOCNMAP:
   1833 	case PIOCMAP:
   1834 	case PIOCGFAULT:
   1835 	case PIOCCFAULT:
   1836 	case PIOCCRED:
   1837 	case PIOCGROUPS:
   1838 	case PIOCUSAGE:
   1839 	case PIOCLUSAGE:
   1840 		break;
   1841 	case PIOCOPENPD:
   1842 		/*
   1843 		 * We will need this below.
   1844 		 * Allocate it now, before locking the process.
   1845 		 */
   1846 		xpnp = prgetnode(vp, PR_OPAGEDATA);
   1847 		break;
   1848 	case PIOCNAUXV:
   1849 	case PIOCAUXV:
   1850 		break;
   1851 
   1852 #if defined(__i386) || defined(__i386_COMPAT)
   1853 	case PIOCNLDT:
   1854 	case PIOCLDT:
   1855 		break;
   1856 #endif	/* __i386 || __i386_COMPAT */
   1857 
   1858 #if defined(__sparc)
   1859 	case PIOCGWIN:
   1860 		thingsize = sizeof (gwindows32_t);
   1861 		break;
   1862 #endif	/* __sparc */
   1863 
   1864 	case PIOCOPENM:		/* open mapped object for reading */
   1865 		if (cmaddr == NULL)
   1866 			un32.va = NULL;
   1867 		else if (copyin(cmaddr, &un32.va, sizeof (un32.va)))
   1868 			error = EFAULT;
   1869 		break;
   1870 
   1871 	case PIOCRUN:		/* make lwp or process runnable */
   1872 		if (cmaddr == NULL)
   1873 			un32.prrun.pr_flags = 0;
   1874 		else if (copyin(cmaddr, &un32.prrun, sizeof (un32.prrun)))
   1875 			error = EFAULT;
   1876 		break;
   1877 
   1878 	case PIOCOPENLWP:	/* return /proc lwp file descriptor */
   1879 		if (copyin(cmaddr, &un32.lwpid, sizeof (un32.lwpid)))
   1880 			error = EFAULT;
   1881 		break;
   1882 
   1883 	case PIOCSTRACE:	/* set signal trace mask */
   1884 		if (copyin(cmaddr, &un32.smask, sizeof (un32.smask)))
   1885 			error = EFAULT;
   1886 		break;
   1887 
   1888 	case PIOCSSIG:		/* set current signal */
   1889 		if (cmaddr == NULL)
   1890 			un32.info.si_signo = 0;
   1891 		else if (copyin(cmaddr, &un32.info, sizeof (un32.info)))
   1892 			error = EFAULT;
   1893 		break;
   1894 
   1895 	case PIOCKILL:		/* send signal */
   1896 	case PIOCUNKILL:	/* delete a signal */
   1897 		if (copyin(cmaddr, &un32.signo, sizeof (un32.signo)))
   1898 			error = EFAULT;
   1899 		break;
   1900 
   1901 	case PIOCNICE:		/* set nice priority */
   1902 		if (copyin(cmaddr, &un32.nice, sizeof (un32.nice)))
   1903 			error = EFAULT;
   1904 		break;
   1905 
   1906 	case PIOCSENTRY:	/* set syscall entry bit mask */
   1907 	case PIOCSEXIT:		/* set syscall exit bit mask */
   1908 		if (copyin(cmaddr, &un32.prmask, sizeof (un32.prmask)))
   1909 			error = EFAULT;
   1910 		break;
   1911 
   1912 	case PIOCSET:		/* set process flags */
   1913 	case PIOCRESET:		/* reset process flags */
   1914 		if (copyin(cmaddr, &un32.flags, sizeof (un32.flags)))
   1915 			error = EFAULT;
   1916 		break;
   1917 
   1918 	case PIOCSREG:		/* set general registers */
   1919 		if (copyin(cmaddr, un32.regs, sizeof (un32.regs)))
   1920 			error = EFAULT;
   1921 		break;
   1922 
   1923 	case PIOCSFPREG:	/* set floating-point registers */
   1924 		if (copyin(cmaddr, &un32.fpregs, sizeof (un32.fpregs)))
   1925 			error = EFAULT;
   1926 		break;
   1927 
   1928 	case PIOCSHOLD:		/* set signal-hold mask */
   1929 		if (copyin(cmaddr, &un32.holdmask, sizeof (un32.holdmask)))
   1930 			error = EFAULT;
   1931 		break;
   1932 
   1933 	case PIOCSFAULT:	/* set mask of traced faults */
   1934 		if (copyin(cmaddr, &un32.fltmask, sizeof (un32.fltmask)))
   1935 			error = EFAULT;
   1936 		break;
   1937 
   1938 	default:
   1939 		error = EINVAL;
   1940 		break;
   1941 	}
   1942 
   1943 	if (error)
   1944 		return (error);
   1945 
   1946 startover:
   1947 	/*
   1948 	 * If we need kmem_alloc()d space then we allocate it now, before
   1949 	 * grabbing the process lock.  Using kmem_alloc(KM_SLEEP) while
   1950 	 * holding the process lock leads to deadlock with the clock thread.
   1951 	 * (The clock thread wakes up the pageout daemon to free up space.
   1952 	 * If the clock thread blocks behind us and we are sleeping waiting
   1953 	 * for space, then space may never become available.)
   1954 	 */
   1955 	if (thingsize) {
   1956 		ASSERT(thing == NULL);
   1957 		thing = kmem_alloc(thingsize, KM_SLEEP);
   1958 	}
   1959 
   1960 	switch (cmd) {
   1961 	case PIOCPSINFO:
   1962 	case PIOCGETPR:
   1963 	case PIOCUSAGE:
   1964 	case PIOCLUSAGE:
   1965 		zdisp = ZYES;
   1966 		break;
   1967 	case PIOCSXREG:		/* set extra registers */
   1968 		/*
   1969 		 * perform copyin before grabbing the process lock
   1970 		 */
   1971 		if (thing) {
   1972 			if (copyin(cmaddr, thing, thingsize)) {
   1973 				kmem_free(thing, thingsize);
   1974 				return (EFAULT);
   1975 			}
   1976 		}
   1977 		/* fall through... */
   1978 	default:
   1979 		zdisp = ZNO;
   1980 		break;
   1981 	}
   1982 
   1983 	if ((error = prlock(pnp, zdisp)) != 0) {
   1984 		if (thing != NULL)
   1985 			kmem_free(thing, thingsize);
   1986 		if (xpnp)
   1987 			prfreenode(xpnp);
   1988 		return (error);
   1989 	}
   1990 
   1991 	pcp = pnp->pr_common;
   1992 	p = pcp->prc_proc;
   1993 	ASSERT(p != NULL);
   1994 
   1995 	/*
   1996 	 * Choose a thread/lwp for the operation.
   1997 	 */
   1998 	if (zdisp == ZNO && cmd != PIOCSTOP && cmd != PIOCWSTOP) {
   1999 		if (pnp->pr_type == PR_LWPIDFILE && cmd != PIOCLSTATUS) {
   2000 			t = pcp->prc_thread;
   2001 			ASSERT(t != NULL);
   2002 		} else {
   2003 			t = prchoose(p);	/* returns locked thread */
   2004 			ASSERT(t != NULL);
   2005 			thread_unlock(t);
   2006 		}
   2007 		lwp = ttolwp(t);
   2008 	}
   2009 
   2010 	error = 0;
   2011 	switch (cmd) {
   2012 
   2013 	case PIOCGETPR:		/* read struct proc */
   2014 	{
   2015 		proc_t *prp = thing;
   2016 
   2017 		*prp = *p;
   2018 		prunlock(pnp);
   2019 		if (copyout(prp, cmaddr, sizeof (proc_t)))
   2020 			error = EFAULT;
   2021 		kmem_free(prp, sizeof (proc_t));
   2022 		thing = NULL;
   2023 		break;
   2024 	}
   2025 
   2026 	case PIOCGETU:		/* read u-area */
   2027 	{
   2028 		user_t *userp = thing;
   2029 
   2030 		up = PTOU(p);
   2031 		*userp = *up;
   2032 		prunlock(pnp);
   2033 		if (copyout(userp, cmaddr, sizeof (user_t)))
   2034 			error = EFAULT;
   2035 		kmem_free(userp, sizeof (user_t));
   2036 		thing = NULL;
   2037 		break;
   2038 	}
   2039 
   2040 	case PIOCOPENM:		/* open mapped object for reading */
   2041 		if (PROCESS_NOT_32BIT(p) && cmaddr != NULL) {
   2042 			prunlock(pnp);
   2043 			error = EOVERFLOW;
   2044 			break;
   2045 		}
   2046 		error = propenm(pnp, cmaddr,
   2047 		    (caddr_t)(uintptr_t)un32.va, rvalp, cr);
   2048 		/* propenm() called prunlock(pnp) */
   2049 		break;
   2050 
   2051 	case PIOCSTOP:		/* stop process or lwp from running */
   2052 	case PIOCWSTOP:		/* wait for process or lwp to stop */
   2053 		/*
   2054 		 * Can't apply to a system process.
   2055 		 */
   2056 		if ((p->p_flag & SSYS) || p->p_as == &kas) {
   2057 			prunlock(pnp);
   2058 			error = EBUSY;
   2059 			break;
   2060 		}
   2061 
   2062 		if (cmd == PIOCSTOP)
   2063 			pr_stop(pnp);
   2064 
   2065 		/*
   2066 		 * If an lwp is waiting for itself or its process, don't wait.
   2067 		 * The lwp will never see the fact that itself is stopped.
   2068 		 */
   2069 		if ((pnp->pr_type == PR_LWPIDFILE)?
   2070 		    (pcp->prc_thread == curthread) : (p == curproc)) {
   2071 			if (cmd == PIOCWSTOP)
   2072 				error = EBUSY;
   2073 			prunlock(pnp);
   2074 			break;
   2075 		}
   2076 
   2077 		if ((error = pr_wait_stop(pnp, (time_t)0)) != 0)
   2078 			break;	/* pr_wait_stop() unlocked the process */
   2079 
   2080 		if (cmaddr == NULL)
   2081 			prunlock(pnp);
   2082 		else if (PROCESS_NOT_32BIT(p)) {
   2083 			prunlock(pnp);
   2084 			error = EOVERFLOW;
   2085 		} else {
   2086 			/*
   2087 			 * Return process/lwp status information.
   2088 			 */
   2089 			t = pr_thread(pnp);	/* returns locked thread */
   2090 			thread_unlock(t);
   2091 			oprgetstatus32(t, &un32.prstat, VTOZONE(vp));
   2092 			prunlock(pnp);
   2093 			if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat)))
   2094 				error = EFAULT;
   2095 		}
   2096 		break;
   2097 
   2098 	case PIOCRUN:		/* make lwp or process runnable */
   2099 	{
   2100 		long flags = un32.prrun.pr_flags;
   2101 
   2102 		/*
   2103 		 * Cannot set an lwp running is it is not stopped.
   2104 		 * Also, no lwp other than the /proc agent lwp can
   2105 		 * be set running so long as the /proc agent lwp exists.
   2106 		 */
   2107 		if ((!ISTOPPED(t) && !VSTOPPED(t) &&
   2108 		    !(t->t_proc_flag & TP_PRSTOP)) ||
   2109 		    (p->p_agenttp != NULL &&
   2110 		    (t != p->p_agenttp || pnp->pr_type != PR_LWPIDFILE))) {
   2111 			prunlock(pnp);
   2112 			error = EBUSY;
   2113 			break;
   2114 		}
   2115 
   2116 		if ((flags & PRSVADDR) && PROCESS_NOT_32BIT(p)) {
   2117 			prunlock(pnp);
   2118 			error = EOVERFLOW;
   2119 			break;
   2120 		}
   2121 
   2122 		if (flags & (PRSHOLD|PRSTRACE|PRSFAULT|PRSVADDR)) {
   2123 			un.prrun.pr_flags = (int)flags;
   2124 			un.prrun.pr_trace = un32.prrun.pr_trace;
   2125 			un.prrun.pr_sighold = un32.prrun.pr_sighold;
   2126 			un.prrun.pr_fault = un32.prrun.pr_fault;
   2127 			un.prrun.pr_vaddr =
   2128 			    (caddr_t)(uintptr_t)un32.prrun.pr_vaddr;
   2129 			prsetrun(t, &un.prrun);
   2130 		}
   2131 
   2132 		error = pr_setrun(pnp, prmaprunflags(flags));
   2133 
   2134 		prunlock(pnp);
   2135 		break;
   2136 	}
   2137 
   2138 	case PIOCLWPIDS:	/* get array of lwp identifiers */
   2139 	{
   2140 		int nlwp;
   2141 		int Nlwp;
   2142 		id_t *idp;
   2143 		id_t *Bidp;
   2144 
   2145 		Nlwp = nlwp = p->p_lwpcnt;
   2146 
   2147 		if (thing && thingsize != (Nlwp+1) * sizeof (id_t)) {
   2148 			kmem_free(thing, thingsize);
   2149 			thing = NULL;
   2150 		}
   2151 		if (thing == NULL) {
   2152 			thingsize = (Nlwp+1) * sizeof (id_t);
   2153 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
   2154 		}
   2155 		if (thing == NULL) {
   2156 			prunlock(pnp);
   2157 			goto startover;
   2158 		}
   2159 
   2160 		idp = thing;
   2161 		thing = NULL;
   2162 		Bidp = idp;
   2163 		if ((t = p->p_tlist) != NULL) {
   2164 			do {
   2165 				ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
   2166 				ASSERT(nlwp > 0);
   2167 				--nlwp;
   2168 				*idp++ = t->t_tid;
   2169 			} while ((t = t->t_forw) != p->p_tlist);
   2170 		}
   2171 		*idp = 0;
   2172 		ASSERT(nlwp == 0);
   2173 		prunlock(pnp);
   2174 		if (copyout(Bidp, cmaddr, (Nlwp+1) * sizeof (id_t)))
   2175 			error = EFAULT;
   2176 		kmem_free(Bidp, (Nlwp+1) * sizeof (id_t));
   2177 		break;
   2178 	}
   2179 
   2180 	case PIOCOPENLWP:	/* return /proc lwp file descriptor */
   2181 	{
   2182 		vnode_t *xvp;
   2183 		int n;
   2184 
   2185 		prunlock(pnp);
   2186 		if ((xvp = prlwpnode(pnp, un32.lwpid)) == NULL)
   2187 			error = ENOENT;
   2188 		else if (error = fassign(&xvp, flag & (FREAD|FWRITE), &n)) {
   2189 			VN_RELE(xvp);
   2190 		} else
   2191 			*rvalp = n;
   2192 		break;
   2193 	}
   2194 
   2195 	case PIOCOPENPD:	/* return /proc page data file descriptor */
   2196 	{
   2197 		vnode_t *xvp = PTOV(xpnp);
   2198 		vnode_t *dp = pnp->pr_parent;
   2199 		int n;
   2200 
   2201 		if (PROCESS_NOT_32BIT(p)) {
   2202 			prunlock(pnp);
   2203 			prfreenode(xpnp);
   2204 			xpnp = NULL;
   2205 			error = EOVERFLOW;
   2206 			break;
   2207 		}
   2208 
   2209 		if (pnp->pr_type == PR_LWPIDFILE) {
   2210 			dp = VTOP(dp)->pr_parent;
   2211 			dp = VTOP(dp)->pr_parent;
   2212 		}
   2213 		ASSERT(VTOP(dp)->pr_type == PR_PIDDIR);
   2214 
   2215 		VN_HOLD(dp);
   2216 		pcp = pnp->pr_pcommon;
   2217 		xpnp->pr_ino = ptoi(pcp->prc_pid);
   2218 		xpnp->pr_common = pcp;
   2219 		xpnp->pr_pcommon = pcp;
   2220 		xpnp->pr_parent = dp;
   2221 
   2222 		xpnp->pr_next = p->p_plist;
   2223 		p->p_plist = xvp;
   2224 
   2225 		prunlock(pnp);
   2226 		if (error = fassign(&xvp, FREAD, &n)) {
   2227 			VN_RELE(xvp);
   2228 		} else
   2229 			*rvalp = n;
   2230 
   2231 		xpnp = NULL;
   2232 		break;
   2233 	}
   2234 
   2235 	case PIOCGTRACE:	/* get signal trace mask */
   2236 		prassignset(&un32.smask, &p->p_sigmask);
   2237 		prunlock(pnp);
   2238 		if (copyout(&un32.smask, cmaddr, sizeof (un32.smask)))
   2239 			error = EFAULT;
   2240 		break;
   2241 
   2242 	case PIOCSTRACE:	/* set signal trace mask */
   2243 		prdelset(&un32.smask, SIGKILL);
   2244 		prassignset(&p->p_sigmask, &un32.smask);
   2245 		if (!sigisempty(&p->p_sigmask))
   2246 			p->p_proc_flag |= P_PR_TRACE;
   2247 		else if (prisempty(&p->p_fltmask)) {
   2248 			up = PTOU(p);
   2249 			if (up->u_systrap == 0)
   2250 				p->p_proc_flag &= ~P_PR_TRACE;
   2251 		}
   2252 		prunlock(pnp);
   2253 		break;
   2254 
   2255 	case PIOCSSIG:		/* set current signal */
   2256 		if (un32.info.si_signo != 0 && PROCESS_NOT_32BIT(p)) {
   2257 			prunlock(pnp);
   2258 			error = EOVERFLOW;
   2259 		} else {
   2260 			bzero(&un.info, sizeof (un.info));
   2261 			siginfo_32tok(&un32.info, (k_siginfo_t *)&un.info);
   2262 			error = pr_setsig(pnp, &un.info);
   2263 			prunlock(pnp);
   2264 			if (un32.info.si_signo == SIGKILL && error == 0)
   2265 				pr_wait_die(pnp);
   2266 		}
   2267 		break;
   2268 
   2269 	case PIOCKILL:		/* send signal */
   2270 		error = pr_kill(pnp, un32.signo, cr);
   2271 		prunlock(pnp);
   2272 		if (un32.signo == SIGKILL && error == 0)
   2273 			pr_wait_die(pnp);
   2274 		break;
   2275 
   2276 	case PIOCUNKILL:	/* delete a signal */
   2277 		error = pr_unkill(pnp, un32.signo);
   2278 		prunlock(pnp);
   2279 		break;
   2280 
   2281 	case PIOCNICE:		/* set nice priority */
   2282 		error = pr_nice(p, un32.nice, cr);
   2283 		prunlock(pnp);
   2284 		break;
   2285 
   2286 	case PIOCGENTRY:	/* get syscall entry bit mask */
   2287 	case PIOCGEXIT:		/* get syscall exit bit mask */
   2288 		up = PTOU(p);
   2289 		if (cmd == PIOCGENTRY) {
   2290 			prassignset(&un32.prmask, &up->u_entrymask);
   2291 		} else {
   2292 			prassignset(&un32.prmask, &up->u_exitmask);
   2293 		}
   2294 		prunlock(pnp);
   2295 		if (copyout(&un32.prmask, cmaddr, sizeof (un32.prmask)))
   2296 			error = EFAULT;
   2297 		break;
   2298 
   2299 	case PIOCSENTRY:	/* set syscall entry bit mask */
   2300 	case PIOCSEXIT:		/* set syscall exit bit mask */
   2301 		pr_setentryexit(p, &un32.prmask, cmd == PIOCSENTRY);
   2302 		prunlock(pnp);
   2303 		break;
   2304 
   2305 	case PIOCSRLC:		/* obsolete: set running on last /proc close */
   2306 		error = pr_set(p, prmapsetflags(PR_RLC));
   2307 		prunlock(pnp);
   2308 		break;
   2309 
   2310 	case PIOCRRLC:		/* obsolete: reset run-on-last-close flag */
   2311 		error = pr_unset(p, prmapsetflags(PR_RLC));
   2312 		prunlock(pnp);
   2313 		break;
   2314 
   2315 	case PIOCSFORK:		/* obsolete: set inherit-on-fork flag */
   2316 		error = pr_set(p, prmapsetflags(PR_FORK));
   2317 		prunlock(pnp);
   2318 		break;
   2319 
   2320 	case PIOCRFORK:		/* obsolete: reset inherit-on-fork flag */
   2321 		error = pr_unset(p, prmapsetflags(PR_FORK));
   2322 		prunlock(pnp);
   2323 		break;
   2324 
   2325 	case PIOCSET:		/* set process flags */
   2326 		error = pr_set(p, prmapsetflags((long)un32.flags));
   2327 		prunlock(pnp);
   2328 		break;
   2329 
   2330 	case PIOCRESET:		/* reset process flags */
   2331 		error = pr_unset(p, prmapsetflags((long)un32.flags));
   2332 		prunlock(pnp);
   2333 		break;
   2334 
   2335 	case PIOCGREG:		/* get general registers */
   2336 		if (PROCESS_NOT_32BIT(p))
   2337 			error = EOVERFLOW;
   2338 		else if (t->t_state != TS_STOPPED && !VSTOPPED(t))
   2339 			bzero(un32.regs, sizeof (un32.regs));
   2340 		else {
   2341 			/* drop p_lock while touching the lwp's stack */
   2342 			mutex_exit(&p->p_lock);
   2343 			prgetprregs32(lwp, un32.regs);
   2344 			mutex_enter(&p->p_lock);
   2345 		}
   2346 		prunlock(pnp);
   2347 		if (error == 0 &&
   2348 		    copyout(un32.regs, cmaddr, sizeof (un32.regs)))
   2349 			error = EFAULT;
   2350 		break;
   2351 
   2352 	case PIOCSREG:		/* set general registers */
   2353 		if (PROCESS_NOT_32BIT(p))
   2354 			error = EOVERFLOW;
   2355 		else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
   2356 			error = EBUSY;
   2357 		else {
   2358 			/* drop p_lock while touching the lwp's stack */
   2359 			mutex_exit(&p->p_lock);
   2360 			prgregset_32ton(lwp, un32.regs, un.regs);
   2361 			prsetprregs(lwp, un.regs, 0);
   2362 			mutex_enter(&p->p_lock);
   2363 		}
   2364 		prunlock(pnp);
   2365 		break;
   2366 
   2367 	case PIOCGFPREG:	/* get floating-point registers */
   2368 		if (!prhasfp())
   2369 			error = EINVAL;	/* No FP support */
   2370 		else if (PROCESS_NOT_32BIT(p))
   2371 			error = EOVERFLOW;
   2372 		else if (t->t_state != TS_STOPPED && !VSTOPPED(t))
   2373 			bzero(&un32.fpregs, sizeof (un32.fpregs));
   2374 		else {
   2375 			/* drop p_lock while touching the lwp's stack */
   2376 			mutex_exit(&p->p_lock);
   2377 			prgetprfpregs32(lwp, &un32.fpregs);
   2378 			mutex_enter(&p->p_lock);
   2379 		}
   2380 		prunlock(pnp);
   2381 		if (error == 0 &&
   2382 		    copyout(&un32.fpregs, cmaddr, sizeof (un32.fpregs)))
   2383 			error = EFAULT;
   2384 		break;
   2385 
   2386 	case PIOCSFPREG:	/* set floating-point registers */
   2387 		if (!prhasfp())
   2388 			error = EINVAL;	/* No FP support */
   2389 		else if (PROCESS_NOT_32BIT(p))
   2390 			error = EOVERFLOW;
   2391 		else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
   2392 			error = EBUSY;
   2393 		else {
   2394 			/* drop p_lock while touching the lwp's stack */
   2395 			mutex_exit(&p->p_lock);
   2396 			prsetprfpregs32(lwp, &un32.fpregs);
   2397 			mutex_enter(&p->p_lock);
   2398 		}
   2399 		prunlock(pnp);
   2400 		break;
   2401 
   2402 	case PIOCGXREGSIZE:	/* get the size of the extra registers */
   2403 	{
   2404 		int xregsize;
   2405 
   2406 		if (prhasx(p)) {
   2407 			xregsize = prgetprxregsize(p);
   2408 			prunlock(pnp);
   2409 			if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
   2410 				error = EFAULT;
   2411 		} else {
   2412 			prunlock(pnp);
   2413 			error = EINVAL;	/* No extra register support */
   2414 		}
   2415 		break;
   2416 	}
   2417 
   2418 	case PIOCGXREG:		/* get extra registers */
   2419 		if (PROCESS_NOT_32BIT(p))
   2420 			error = EOVERFLOW;
   2421 		else if (!prhasx(p))
   2422 			error = EINVAL;	/* No extra register support */
   2423 		else {
   2424 			bzero(thing, thingsize);
   2425 			if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
   2426 				/* drop p_lock to touch the stack */
   2427 				mutex_exit(&p->p_lock);
   2428 				prgetprxregs(lwp, thing);
   2429 				mutex_enter(&p->p_lock);
   2430 			}
   2431 		}
   2432 		prunlock(pnp);
   2433 		if (error == 0 &&
   2434 		    copyout(thing, cmaddr, thingsize))
   2435 			error = EFAULT;
   2436 		if (thing) {
   2437 			kmem_free(thing, thingsize);
   2438 			thing = NULL;
   2439 		}
   2440 		break;
   2441 
   2442 	case PIOCSXREG:		/* set extra registers */
   2443 		if (PROCESS_NOT_32BIT(p))
   2444 			error = EOVERFLOW;
   2445 		else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
   2446 			error = EBUSY;
   2447 		else if (!prhasx(p))
   2448 			error = EINVAL;	/* No extra register support */
   2449 		else if (thing) {
   2450 			/* drop p_lock while touching the lwp's stack */
   2451 			mutex_exit(&p->p_lock);
   2452 			prsetprxregs(lwp, thing);
   2453 			mutex_enter(&p->p_lock);
   2454 		}
   2455 		prunlock(pnp);
   2456 		if (thing) {
   2457 			kmem_free(thing, thingsize);
   2458 			thing = NULL;
   2459 		}
   2460 		break;
   2461 
   2462 	case PIOCSTATUS:	/* get process/lwp status */
   2463 		if (PROCESS_NOT_32BIT(p)) {
   2464 			prunlock(pnp);
   2465 			error = EOVERFLOW;
   2466 			break;
   2467 		}
   2468 		oprgetstatus32(t, &un32.prstat, VTOZONE(vp));
   2469 		prunlock(pnp);
   2470 		if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat)))
   2471 			error = EFAULT;
   2472 		break;
   2473 
   2474 	case PIOCLSTATUS:	/* get status for process & all lwps */
   2475 	{
   2476 		int Nlwp;
   2477 		int nlwp;
   2478 		prstatus32_t *Bprsp;
   2479 		prstatus32_t *prsp;
   2480 
   2481 		if (PROCESS_NOT_32BIT(p)) {
   2482 			prunlock(pnp);
   2483 			if (thing) {
   2484 				kmem_free(thing, thingsize);
   2485 				thing = NULL;
   2486 			}
   2487 			error = EOVERFLOW;
   2488 			break;
   2489 		}
   2490 
   2491 		nlwp = Nlwp = p->p_lwpcnt;
   2492 
   2493 		if (thing && thingsize != (Nlwp+1) * sizeof (prstatus32_t)) {
   2494 			kmem_free(thing, thingsize);
   2495 			thing = NULL;
   2496 		}
   2497 		if (thing == NULL) {
   2498 			thingsize = (Nlwp+1) * sizeof (prstatus32_t);
   2499 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
   2500 		}
   2501 		if (thing == NULL) {
   2502 			prunlock(pnp);
   2503 			goto startover;
   2504 		}
   2505 
   2506 		Bprsp = (prstatus32_t *)thing;
   2507 		thing = NULL;
   2508 		prsp = Bprsp;
   2509 		oprgetstatus32(t, prsp, VTOZONE(vp));
   2510 		t = p->p_tlist;
   2511 		do {
   2512 			ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
   2513 			ASSERT(nlwp > 0);
   2514 			--nlwp;
   2515 			oprgetstatus32(t, ++prsp, VTOZONE(vp));
   2516 		} while ((t = t->t_forw) != p->p_tlist);
   2517 		ASSERT(nlwp == 0);
   2518 		prunlock(pnp);
   2519 		if (copyout(Bprsp, cmaddr, (Nlwp+1) * sizeof (prstatus32_t)))
   2520 			error = EFAULT;
   2521 
   2522 		kmem_free(Bprsp, (Nlwp + 1) * sizeof (prstatus32_t));
   2523 		break;
   2524 	}
   2525 
   2526 	case PIOCPSINFO:	/* get ps(1) information */
   2527 	{
   2528 		prpsinfo32_t *psp = &un32.prps;
   2529 
   2530 		oprgetpsinfo32(p, psp,
   2531 		    (pnp->pr_type == PR_LWPIDFILE)? pcp->prc_thread : NULL);
   2532 
   2533 		prunlock(pnp);
   2534 		if (copyout(&un32.prps, cmaddr, sizeof (un32.prps)))
   2535 			error = EFAULT;
   2536 		break;
   2537 	}
   2538 
   2539 	case PIOCMAXSIG:	/* get maximum signal number */
   2540 	{
   2541 		int n = nsig-1;
   2542 
   2543 		prunlock(pnp);
   2544 		if (copyout(&n, cmaddr, sizeof (int)))
   2545 			error = EFAULT;
   2546 		break;
   2547 	}
   2548 
   2549 	case PIOCACTION:	/* get signal action structures */
   2550 	{
   2551 		uint_t sig;
   2552 		struct sigaction32 *sap = thing;
   2553 
   2554 		if (PROCESS_NOT_32BIT(p))
   2555 			error = EOVERFLOW;
   2556 		else {
   2557 			up = PTOU(p);
   2558 			for (sig = 1; sig < nsig; sig++)
   2559 				prgetaction32(p, up, sig, &sap[sig-1]);
   2560 		}
   2561 		prunlock(pnp);
   2562 		if (error == 0 &&
   2563 		    copyout(sap, cmaddr, (nsig-1)*sizeof (struct sigaction32)))
   2564 			error = EFAULT;
   2565 		kmem_free(sap, (nsig-1)*sizeof (struct sigaction32));
   2566 		thing = NULL;
   2567 		break;
   2568 	}
   2569 
   2570 	case PIOCGHOLD:		/* get signal-hold mask */
   2571 		schedctl_finish_sigblock(t);
   2572 		sigktou(&t->t_hold, &un32.holdmask);
   2573 		prunlock(pnp);
   2574 		if (copyout(&un32.holdmask, cmaddr, sizeof (un32.holdmask)))
   2575 			error = EFAULT;
   2576 		break;
   2577 
   2578 	case PIOCSHOLD:		/* set signal-hold mask */
   2579 		pr_sethold(pnp, &un32.holdmask);
   2580 		prunlock(pnp);
   2581 		break;
   2582 
   2583 	case PIOCNMAP:		/* get number of memory mappings */
   2584 	{
   2585 		int n;
   2586 		struct as *as = p->p_as;
   2587 
   2588 		if ((p->p_flag & SSYS) || as == &kas)
   2589 			n = 0;
   2590 		else {
   2591 			mutex_exit(&p->p_lock);
   2592 			AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
   2593 			n = prnsegs(as, 0);
   2594 			AS_LOCK_EXIT(as, &as->a_lock);
   2595 			mutex_enter(&p->p_lock);
   2596 		}
   2597 		prunlock(pnp);
   2598 		if (copyout(&n, cmaddr, sizeof (int)))
   2599 			error = EFAULT;
   2600 		break;
   2601 	}
   2602 
   2603 	case PIOCMAP:		/* get memory map information */
   2604 	{
   2605 		list_t iolhead;
   2606 		struct as *as = p->p_as;
   2607 
   2608 		if ((p->p_flag & SSYS) || as == &kas) {
   2609 			error = 0;
   2610 			prunlock(pnp);
   2611 		} else if (PROCESS_NOT_32BIT(p)) {
   2612 			error = EOVERFLOW;
   2613 			prunlock(pnp);
   2614 		} else {
   2615 			mutex_exit(&p->p_lock);
   2616 			AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
   2617 			error = oprgetmap32(p, &iolhead);
   2618 			AS_LOCK_EXIT(as, &as->a_lock);
   2619 			mutex_enter(&p->p_lock);
   2620 			prunlock(pnp);
   2621 
   2622 			error = pr_iol_copyout_and_free(&iolhead,
   2623 			    &cmaddr, error);
   2624 		}
   2625 		/*
   2626 		 * The procfs PIOCMAP ioctl returns an all-zero buffer
   2627 		 * to indicate the end of the prmap[] array.
   2628 		 * Append it to whatever has already been copied out.
   2629 		 */
   2630 		bzero(&un32.prmap, sizeof (un32.prmap));
   2631 		if (!error &&
   2632 		    copyout(&un32.prmap, cmaddr, sizeof (un32.prmap)))
   2633 				error = EFAULT;
   2634 		break;
   2635 	}
   2636 
   2637 	case PIOCGFAULT:	/* get mask of traced faults */
   2638 		prassignset(&un32.fltmask, &p->p_fltmask);
   2639 		prunlock(pnp);
   2640 		if (copyout(&un32.fltmask, cmaddr, sizeof (un32.fltmask)))
   2641 			error = EFAULT;
   2642 		break;
   2643 
   2644 	case PIOCSFAULT:	/* set mask of traced faults */
   2645 		pr_setfault(p, &un32.fltmask);
   2646 		prunlock(pnp);
   2647 		break;
   2648 
   2649 	case PIOCCFAULT:	/* clear current fault */
   2650 		lwp->lwp_curflt = 0;
   2651 		prunlock(pnp);
   2652 		break;
   2653 
   2654 	case PIOCCRED:		/* get process credentials */
   2655 	{
   2656 		cred_t *cp;
   2657 
   2658 		mutex_enter(&p->p_crlock);
   2659 		cp = p->p_cred;
   2660 		un32.prcred.pr_euid = crgetuid(cp);
   2661 		un32.prcred.pr_ruid = crgetruid(cp);
   2662 		un32.prcred.pr_suid = crgetsuid(cp);
   2663 		un32.prcred.pr_egid = crgetgid(cp);
   2664 		un32.prcred.pr_rgid = crgetrgid(cp);
   2665 		un32.prcred.pr_sgid = crgetsgid(cp);
   2666 		un32.prcred.pr_ngroups = crgetngroups(cp);
   2667 		mutex_exit(&p->p_crlock);
   2668 
   2669 		prunlock(pnp);
   2670 		if (copyout(&un32.prcred, cmaddr, sizeof (un32.prcred)))
   2671 			error = EFAULT;
   2672 		break;
   2673 	}
   2674 
   2675 	case PIOCGROUPS:	/* get supplementary groups */
   2676 	{
   2677 		cred_t *cp;
   2678 
   2679 		mutex_enter(&p->p_crlock);
   2680 		cp = p->p_cred;
   2681 		crhold(cp);
   2682 		mutex_exit(&p->p_crlock);
   2683 
   2684 		prunlock(pnp);
   2685 		if (copyout(crgetgroups(cp), cmaddr,
   2686 		    MAX(crgetngroups(cp), 1) * sizeof (gid_t)))
   2687 			error = EFAULT;
   2688 		crfree(cp);
   2689 		break;
   2690 	}
   2691 
   2692 	case PIOCUSAGE:		/* get usage info */
   2693 	{
   2694 		/*
   2695 		 * For an lwp file descriptor, return just the lwp usage.
   2696 		 * For a process file descriptor, return total usage,
   2697 		 * all current lwps plus all defunct lwps.
   2698 		 */
   2699 		prhusage_t *pup = &un32.prhusage;
   2700 		prusage32_t *upup;
   2701 
   2702 		bzero(pup, sizeof (*pup));
   2703 		pup->pr_tstamp = gethrtime();
   2704 
   2705 		if (pnp->pr_type == PR_LWPIDFILE) {
   2706 			t = pcp->prc_thread;
   2707 			if (t != NULL)
   2708 				prgetusage(t, pup);
   2709 			else
   2710 				error = ENOENT;
   2711 		} else {
   2712 			pup->pr_count  = p->p_defunct;
   2713 			pup->pr_create = p->p_mstart;
   2714 			pup->pr_term   = p->p_mterm;
   2715 
   2716 			pup->pr_rtime    = p->p_mlreal;
   2717 			pup->pr_utime    = p->p_acct[LMS_USER];
   2718 			pup->pr_stime    = p->p_acct[LMS_SYSTEM];
   2719 			pup->pr_ttime    = p->p_acct[LMS_TRAP];
   2720 			pup->pr_tftime   = p->p_acct[LMS_TFAULT];
   2721 			pup->pr_dftime   = p->p_acct[LMS_DFAULT];
   2722 			pup->pr_kftime   = p->p_acct[LMS_KFAULT];
   2723 			pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
   2724 			pup->pr_slptime  = p->p_acct[LMS_SLEEP];
   2725 			pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
   2726 			pup->pr_stoptime = p->p_acct[LMS_STOPPED];
   2727 
   2728 			pup->pr_minf  = p->p_ru.minflt;
   2729 			pup->pr_majf  = p->p_ru.majflt;
   2730 			pup->pr_nswap = p->p_ru.nswap;
   2731 			pup->pr_inblk = p->p_ru.inblock;
   2732 			pup->pr_oublk = p->p_ru.oublock;
   2733 			pup->pr_msnd  = p->p_ru.msgsnd;
   2734 			pup->pr_mrcv  = p->p_ru.msgrcv;
   2735 			pup->pr_sigs  = p->p_ru.nsignals;
   2736 			pup->pr_vctx  = p->p_ru.nvcsw;
   2737 			pup->pr_ictx  = p->p_ru.nivcsw;
   2738 			pup->pr_sysc  = p->p_ru.sysc;
   2739 			pup->pr_ioch  = p->p_ru.ioch;
   2740 
   2741 			/*
   2742 			 * Add the usage information for each active lwp.
   2743 			 */
   2744 			if ((t = p->p_tlist) != NULL &&
   2745 			    !(pcp->prc_flags & PRC_DESTROY)) {
   2746 				do {
   2747 					ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
   2748 					pup->pr_count++;
   2749 					praddusage(t, pup);
   2750 				} while ((t = t->t_forw) != p->p_tlist);
   2751 			}
   2752 		}
   2753 
   2754 		prunlock(pnp);
   2755 
   2756 		upup = kmem_alloc(sizeof (*upup), KM_SLEEP);
   2757 		prcvtusage32(pup, upup);
   2758 		if (copyout(upup, cmaddr, sizeof (*upup)))
   2759 			error = EFAULT;
   2760 		kmem_free(upup, sizeof (*upup));
   2761 
   2762 		break;
   2763 	}
   2764 
   2765 	case PIOCLUSAGE:	/* get detailed usage info */
   2766 	{
   2767 		int Nlwp;
   2768 		int nlwp;
   2769 		prusage32_t *upup;
   2770 		prusage32_t *Bupup;
   2771 		prhusage_t *pup;
   2772 		hrtime_t curtime;
   2773 
   2774 		nlwp = Nlwp = (pcp->prc_flags & PRC_DESTROY)? 0 : p->p_lwpcnt;
   2775 
   2776 		if (thing && thingsize !=
   2777 		    sizeof (prhusage_t) + (Nlwp+1) * sizeof (prusage32_t)) {
   2778 			kmem_free(thing, thingsize);
   2779 			thing = NULL;
   2780 		}
   2781 		if (thing == NULL) {
   2782 			thingsize = sizeof (prhusage_t) +
   2783 			    (Nlwp+1) * sizeof (prusage32_t);
   2784 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
   2785 		}
   2786 		if (thing == NULL) {
   2787 			prunlock(pnp);
   2788 			goto startover;
   2789 		}
   2790 
   2791 		pup = (prhusage_t *)thing;
   2792 		upup = Bupup = (prusage32_t *)(pup + 1);
   2793 
   2794 		ASSERT(p == pcp->prc_proc);
   2795 
   2796 		curtime = gethrtime();
   2797 
   2798 		/*
   2799 		 * First the summation over defunct lwps.
   2800 		 */
   2801 		bzero(pup, sizeof (*pup));
   2802 		pup->pr_count  = p->p_defunct;
   2803 		pup->pr_tstamp = curtime;
   2804 		pup->pr_create = p->p_mstart;
   2805 		pup->pr_term   = p->p_mterm;
   2806 
   2807 		pup->pr_rtime    = p->p_mlreal;
   2808 		pup->pr_utime    = p->p_acct[LMS_USER];
   2809 		pup->pr_stime    = p->p_acct[LMS_SYSTEM];
   2810 		pup->pr_ttime    = p->p_acct[LMS_TRAP];
   2811 		pup->pr_tftime   = p->p_acct[LMS_TFAULT];
   2812 		pup->pr_dftime   = p->p_acct[LMS_DFAULT];
   2813 		pup->pr_kftime   = p->p_acct[LMS_KFAULT];
   2814 		pup->pr_ltime    = p->p_acct[LMS_USER_LOCK];
   2815 		pup->pr_slptime  = p->p_acct[LMS_SLEEP];
   2816 		pup->pr_wtime    = p->p_acct[LMS_WAIT_CPU];
   2817 		pup->pr_stoptime = p->p_acct[LMS_STOPPED];
   2818 
   2819 		pup->pr_minf  = p->p_ru.minflt;
   2820 		pup->pr_majf  = p->p_ru.majflt;
   2821 		pup->pr_nswap = p->p_ru.nswap;
   2822 		pup->pr_inblk = p->p_ru.inblock;
   2823 		pup->pr_oublk = p->p_ru.oublock;
   2824 		pup->pr_msnd  = p->p_ru.msgsnd;
   2825 		pup->pr_mrcv  = p->p_ru.msgrcv;
   2826 		pup->pr_sigs  = p->p_ru.nsignals;
   2827 		pup->pr_vctx  = p->p_ru.nvcsw;
   2828 		pup->pr_ictx  = p->p_ru.nivcsw;
   2829 		pup->pr_sysc  = p->p_ru.sysc;
   2830 		pup->pr_ioch  = p->p_ru.ioch;
   2831 
   2832 		prcvtusage32(pup, upup);
   2833 
   2834 		/*
   2835 		 * Fill one prusage struct for each active lwp.
   2836 		 */
   2837 		if ((t = p->p_tlist) != NULL &&
   2838 		    !(pcp->prc_flags & PRC_DESTROY)) {
   2839 			do {
   2840 				ASSERT(!(t->t_proc_flag & TP_LWPEXIT));
   2841 				ASSERT(nlwp > 0);
   2842 				--nlwp;
   2843 				upup++;
   2844 				prgetusage(t, pup);
   2845 				prcvtusage32(pup, upup);
   2846 			} while ((t = t->t_forw) != p->p_tlist);
   2847 		}
   2848 		ASSERT(nlwp == 0);
   2849 
   2850 		prunlock(pnp);
   2851 		if (copyout(Bupup, cmaddr, (Nlwp+1) * sizeof (prusage32_t)))
   2852 			error = EFAULT;
   2853 		kmem_free(thing, thingsize);
   2854 		thing = NULL;
   2855 		break;
   2856 	}
   2857 
   2858 	case PIOCNAUXV:		/* get number of aux vector entries */
   2859 	{
   2860 		int n = __KERN_NAUXV_IMPL;
   2861 
   2862 		prunlock(pnp);
   2863 		if (copyout(&n, cmaddr, sizeof (int)))
   2864 			error = EFAULT;
   2865 		break;
   2866 	}
   2867 
   2868 	case PIOCAUXV:		/* get aux vector (see sys/auxv.h) */
   2869 	{
   2870 		int i;
   2871 
   2872 		if (PROCESS_NOT_32BIT(p)) {
   2873 			prunlock(pnp);
   2874 			error = EOVERFLOW;
   2875 		} else {
   2876 			up = PTOU(p);
   2877 			for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
   2878 				un32.auxv[i].a_type = up->u_auxv[i].a_type;
   2879 				un32.auxv[i].a_un.a_val =
   2880 				    (int32_t)up->u_auxv[i].a_un.a_val;
   2881 			}
   2882 			prunlock(pnp);
   2883 			if (copyout(un32.auxv, cmaddr,
   2884 			    __KERN_NAUXV_IMPL * sizeof (auxv32_t)))
   2885 				error = EFAULT;
   2886 		}
   2887 		break;
   2888 	}
   2889 
   2890 #if defined(__i386) || defined(__i386_COMPAT)
   2891 	case PIOCNLDT:		/* get number of LDT entries */
   2892 	{
   2893 		int n;
   2894 
   2895 		mutex_exit(&p->p_lock);
   2896 		mutex_enter(&p->p_ldtlock);
   2897 		n = prnldt(p);
   2898 		mutex_exit(&p->p_ldtlock);
   2899 		mutex_enter(&p->p_lock);
   2900 		prunlock(pnp);
   2901 		if (copyout(&n, cmaddr, sizeof (n)))
   2902 			error = EFAULT;
   2903 		break;
   2904 	}
   2905 
   2906 	case PIOCLDT:		/* get LDT entries */
   2907 	{
   2908 		struct ssd *ssd;
   2909 		int n;
   2910 
   2911 		mutex_exit(&p->p_lock);
   2912 		mutex_enter(&p->p_ldtlock);
   2913 		n = prnldt(p);
   2914 
   2915 		if (thing && thingsize != (n+1) * sizeof (*ssd)) {
   2916 			kmem_free(thing, thingsize);
   2917 			thing = NULL;
   2918 		}
   2919 		if (thing == NULL) {
   2920 			thingsize = (n+1) * sizeof (*ssd);
   2921 			thing = kmem_alloc(thingsize, KM_NOSLEEP);
   2922 		}
   2923 		if (thing == NULL) {
   2924 			mutex_exit(&p->p_ldtlock);
   2925 			mutex_enter(&p->p_lock);
   2926 			prunlock(pnp);
   2927 			goto startover;
   2928 		}
   2929 
   2930 		ssd = thing;
   2931 		thing = NULL;
   2932 		if (n != 0)
   2933 			prgetldt(p, ssd);
   2934 		mutex_exit(&p->p_ldtlock);
   2935 		mutex_enter(&p->p_lock);
   2936 		prunlock(pnp);
   2937 
   2938 		/* mark the end of the list with a null entry */
   2939 		bzero(&ssd[n], sizeof (*ssd));
   2940 		if (copyout(ssd, cmaddr, (n+1) * sizeof (*ssd)))
   2941 			error = EFAULT;
   2942 		kmem_free(ssd, (n+1) * sizeof (*ssd));
   2943 		break;
   2944 	}
   2945 #endif	/* __i386 || __i386_COMPAT */
   2946 
   2947 #if defined(__sparc)
   2948 	case PIOCGWIN:		/* get gwindows_t (see sys/reg.h) */
   2949 	{
   2950 		gwindows32_t *gwp = thing;
   2951 
   2952 		if (PROCESS_NOT_32BIT(p)) {
   2953 			prunlock(pnp);
   2954 			error = EOVERFLOW;
   2955 		} else {
   2956 			/* drop p->p_lock while touching the stack */
   2957 			mutex_exit(&p->p_lock);
   2958 			bzero(gwp, sizeof (*gwp));
   2959 			prgetwindows32(lwp, gwp);
   2960 			mutex_enter(&p->p_lock);
   2961 			prunlock(pnp);
   2962 			if (copyout(gwp, cmaddr, sizeof (*gwp)))
   2963 				error = EFAULT;
   2964 		}
   2965 		kmem_free(gwp, sizeof (*gwp));
   2966 		thing = NULL;
   2967 		break;
   2968 	}
   2969 #endif	/* __sparc */
   2970 
   2971 	default:
   2972 		prunlock(pnp);
   2973 		error = EINVAL;
   2974 		break;
   2975 
   2976 	}
   2977 
   2978 	ASSERT(thing == NULL);
   2979 	ASSERT(xpnp == NULL);
   2980 	return (error);
   2981 }
   2982 #endif	/* _SYSCALL32_IMPL */
   2983 
   2984 /*
   2985  * Distinguish "writeable" ioctl requests from others.
   2986  */
   2987 static int
   2988 isprwrioctl(int cmd)
   2989 {
   2990 	switch (cmd) {
   2991 	case PIOCSTOP:
   2992 	case PIOCRUN:
   2993 	case PIOCSTRACE:
   2994 	case PIOCSSIG:
   2995 	case PIOCKILL:
   2996 	case PIOCUNKILL:
   2997 	case PIOCNICE:
   2998 	case PIOCSENTRY:
   2999 	case PIOCSEXIT:
   3000 	case PIOCSRLC:
   3001 	case PIOCRRLC:
   3002 	case PIOCSREG:
   3003 	case PIOCSFPREG:
   3004 	case PIOCSXREG:
   3005 	case PIOCSHOLD:
   3006 	case PIOCSFAULT:
   3007 	case PIOCCFAULT:
   3008 	case PIOCSFORK:
   3009 	case PIOCRFORK:
   3010 	case PIOCSET:
   3011 	case PIOCRESET:
   3012 		return (1);
   3013 	}
   3014 	return (0);
   3015 }
   3016 
   3017 /*
   3018  * Map the ioctl() interface run flags to the new interface run flags.
   3019  */
   3020 static ulong_t
   3021 prmaprunflags(long flags)
   3022 {
   3023 	ulong_t newflags = 0;
   3024 
   3025 	if (flags & PRCSIG)
   3026 		newflags |= 0x01;
   3027 	if (flags & PRCFAULT)
   3028 		newflags |= 0x02;
   3029 	if (flags & PRSTEP)
   3030 		newflags |= 0x04;
   3031 	if (flags & PRSABORT)
   3032 		newflags |= 0x08;
   3033 	if (flags & PRSTOP)
   3034 		newflags |= 0x10;
   3035 	return (newflags);
   3036 }
   3037 
   3038 /*
   3039  * Map the ioctl() interface settable mode flags to the new interface flags.
   3040  */
   3041 static long
   3042 prmapsetflags(long flags)
   3043 {
   3044 	long newflags = 0;
   3045 
   3046 #define	ALLFLAGS	\
   3047 	(PR_FORK|PR_RLC|PR_KLC|PR_ASYNC|PR_BPTADJ|PR_MSACCT|PR_PCOMPAT)
   3048 
   3049 	if (flags & ~ALLFLAGS)
   3050 		newflags = 0xffff;	/* forces EINVAL */
   3051 	if (flags & PR_FORK)
   3052 		newflags |= (0x00100000 | 0x08000000);
   3053 	if (flags & PR_RLC)
   3054 		newflags |= 0x00200000;
   3055 	if (flags & PR_KLC)
   3056 		newflags |= 0x00400000;
   3057 	if (flags & PR_ASYNC)
   3058 		newflags |= 0x00800000;
   3059 	if (flags & PR_MSACCT)
   3060 		newflags |= 0x01000000;
   3061 	if (flags & PR_BPTADJ)
   3062 		newflags |= 0x02000000;
   3063 	if (flags & PR_PCOMPAT)
   3064 		newflags |= 0x04000000;
   3065 	return (newflags);
   3066 }
   3067 
   3068 /*
   3069  * Apply PIOCRUN options specific to the ioctl() interface.
   3070  */
   3071 static void
   3072 prsetrun(kthread_t *t, prrun_t *prp)
   3073 {
   3074 	proc_t *p = ttoproc(t);
   3075 	klwp_t *lwp = ttolwp(t);
   3076 	long flags = prp->pr_flags;
   3077 	user_t *up = PTOU(p);
   3078 
   3079 	ASSERT(MUTEX_HELD(&p->p_lock));
   3080 
   3081 	if (flags & PRSHOLD) {
   3082 		schedctl_finish_sigblock(t);
   3083 		sigutok(&prp->pr_sighold, &t->t_hold);
   3084 		t->t_sig_check = 1;	/* so ISSIG will be done */
   3085 	}
   3086 	if (flags & PRSTRACE) {
   3087 		prdelset(&prp->pr_trace, SIGKILL);
   3088 		prassignset(&p->p_sigmask, &prp->pr_trace);
   3089 		if (!sigisempty(&p->p_sigmask))
   3090 			p->p_proc_flag |= P_PR_TRACE;
   3091 		else if (prisempty(&p->p_fltmask)) {
   3092 			if (up->u_systrap == 0)
   3093 				p->p_proc_flag &= ~P_PR_TRACE;
   3094 		}
   3095 	}
   3096 	if (flags & PRSFAULT) {
   3097 		prassignset(&p->p_fltmask, &prp->pr_fault);
   3098 		if (!prisempty(&p->p_fltmask))
   3099 			p->p_proc_flag |= P_PR_TRACE;
   3100 		else if (sigisempty(&p->p_sigmask)) {
   3101 			if (up->u_systrap == 0)
   3102 				p->p_proc_flag &= ~P_PR_TRACE;
   3103 		}
   3104 	}
   3105 	/*
   3106 	 * prsvaddr() must be called before prstep() because
   3107 	 * stepping can depend on the current value of the PC.
   3108 	 * We drop p_lock while touching the lwp's registers (on stack).
   3109 	 */
   3110 	if (flags & PRSVADDR) {
   3111 		mutex_exit(&p->p_lock);
   3112 		prsvaddr(lwp, prp->pr_vaddr);
   3113 		mutex_enter(&p->p_lock);
   3114 	}
   3115 }
   3116 
   3117 /*
   3118  * Common code for PIOCOPENM
   3119  * Returns with the process unlocked.
   3120  */
   3121 static int
   3122 propenm(prnode_t *pnp, caddr_t cmaddr, caddr_t va, int *rvalp, cred_t *cr)
   3123 {
   3124 	proc_t *p = pnp->pr_common->prc_proc;
   3125 	struct as *as = p->p_as;
   3126 	int error = 0;
   3127 	struct seg *seg;
   3128 	struct vnode *xvp;
   3129 	int n;
   3130 
   3131 	/*
   3132 	 * By fiat, a system process has no address space.
   3133 	 */
   3134 	if ((p->p_flag & SSYS) || as == &kas) {
   3135 		error = EINVAL;
   3136 	} else if (cmaddr) {
   3137 		/*
   3138 		 * We drop p_lock before grabbing the address
   3139 		 * space lock in order to avoid a deadlock with
   3140 		 * the clock thread.  The process will not
   3141 		 * disappear and its address space will not
   3142 		 * change because it is marked P_PR_LOCK.
   3143 		 */
   3144 		mutex_exit(&p->p_lock);
   3145 		AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
   3146 		seg = as_segat(as, va);
   3147 		if (seg != NULL &&
   3148 		    seg->s_ops == &segvn_ops &&
   3149 		    SEGOP_GETVP(seg, va, &xvp) == 0 &&
   3150 		    xvp != NULL &&
   3151 		    xvp->v_type == VREG) {
   3152 			VN_HOLD(xvp);
   3153 		} else {
   3154 			error = EINVAL;
   3155 		}
   3156 		AS_LOCK_EXIT(as, &as->a_lock);
   3157 		mutex_enter(&p->p_lock);
   3158 	} else if ((xvp = p->p_exec) == NULL) {
   3159 		error = EINVAL;
   3160 	} else {
   3161 		VN_HOLD(xvp);
   3162 	}
   3163 
   3164 	prunlock(pnp);
   3165 
   3166 	if (error == 0) {
   3167 		if ((error = VOP_ACCESS(xvp, VREAD, 0, cr, NULL)) == 0)
   3168 			error = fassign(&xvp, FREAD, &n);
   3169 		if (error) {
   3170 			VN_RELE(xvp);
   3171 		} else {
   3172 			*rvalp = n;
   3173 		}
   3174 	}
   3175 
   3176 	return (error);
   3177 }
   3178 
   3179 /*
   3180  * Return old version of process/lwp status.
   3181  * The u-block is mapped in by this routine and unmapped at the end.
   3182  */
   3183 void
   3184 oprgetstatus(kthread_t *t, prstatus_t *sp, zone_t *zp)
   3185 {
   3186 	proc_t *p = ttoproc(t);
   3187 	klwp_t *lwp = ttolwp(t);
   3188 	int flags;
   3189 	user_t *up;
   3190 	ulong_t instr;
   3191 
   3192 	ASSERT(MUTEX_HELD(&p->p_lock));
   3193 
   3194 	up = PTOU(p);
   3195 	bzero(sp, sizeof (*sp));
   3196 	flags = 0;
   3197 	if (t->t_state == TS_STOPPED) {
   3198 		flags |= PR_STOPPED;
   3199 		if ((t->t_schedflag & TS_PSTART) == 0)
   3200 			flags |= PR_ISTOP;
   3201 	} else if (VSTOPPED(t)) {
   3202 		flags |= PR_STOPPED|PR_ISTOP;
   3203 	}
   3204 	if (!(flags & PR_ISTOP) && (t->t_proc_flag & TP_PRSTOP))
   3205 		flags |= PR_DSTOP;
   3206 	if (lwp->lwp_asleep)
   3207 		flags |= PR_ASLEEP;
   3208 	if (p->p_proc_flag & P_PR_FORK)
   3209 		flags |= PR_FORK;
   3210 	if (p->p_proc_flag & P_PR_RUNLCL)
   3211 		flags |= PR_RLC;
   3212 	if (p->p_proc_flag & P_PR_KILLCL)
   3213 		flags |= PR_KLC;
   3214 	if (p->p_proc_flag & P_PR_ASYNC)
   3215 		flags |= PR_ASYNC;
   3216 	if (p->p_proc_flag & P_PR_BPTADJ)
   3217 		flags |= PR_BPTADJ;
   3218 	if (p->p_proc_flag & P_PR_PTRACE)
   3219 		flags |= PR_PCOMPAT;
   3220 	if (t->t_proc_flag & TP_MSACCT)
   3221 		flags |= PR_MSACCT;
   3222 	sp->pr_flags = flags;
   3223 	if (VSTOPPED(t)) {
   3224 		sp->pr_why   = PR_REQUESTED;
   3225 		sp->pr_what  = 0;
   3226 	} else {
   3227 		sp->pr_why   = t->t_whystop;
   3228 		sp->pr_what  = t->t_whatstop;
   3229 	}
   3230 
   3231 	if (t->t_whystop == PR_FAULTED)
   3232 		bcopy(&lwp->lwp_siginfo,
   3233 		    &sp->pr_info, sizeof (k_siginfo_t));
   3234 	else if (lwp->lwp_curinfo)
   3235 		bcopy(&lwp->lwp_curinfo->sq_info,
   3236 		    &sp->pr_info, sizeof (k_siginfo_t));
   3237 
   3238 	if (SI_FROMUSER(&lwp->lwp_siginfo) && zp->zone_id != GLOBAL_ZONEID &&
   3239 	    sp->pr_info.si_zoneid != zp->zone_id) {
   3240 		sp->pr_info.si_pid = zp->zone_zsched->p_pid;
   3241 		sp->pr_info.si_uid = 0;
   3242 		sp->pr_info.si_ctid = -1;
   3243 		sp->pr_info.si_zoneid = zp->zone_id;
   3244 	}
   3245 
   3246 	sp->pr_cursig  = lwp->lwp_cursig;
   3247 	prassignset(&sp->pr_sigpend, &p->p_sig);
   3248 	prassignset(&sp->pr_lwppend, &t->t_sig);
   3249 	schedctl_finish_sigblock(t);
   3250 	prassignset(&sp->pr_sighold, &t->t_hold);
   3251 	sp->pr_altstack = lwp->lwp_sigaltstack;
   3252 	prgetaction(p, up, lwp->lwp_cursig, &sp->pr_action);
   3253 	sp->pr_pid   = p->p_pid;
   3254 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
   3255 	    (p->p_flag & SZONETOP)) {
   3256 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
   3257 		/*
   3258 		 * Inside local zones, fake zsched's pid as parent pids for
   3259 		 * processes which reference processes outside of the zone.
   3260 		 */
   3261 		sp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
   3262 	} else {
   3263 		sp->pr_ppid = p->p_ppid;
   3264 	}
   3265 	sp->pr_pgrp  = p->p_pgrp;
   3266 	sp->pr_sid   = p->p_sessp->s_sid;
   3267 	hrt2ts(mstate_aggr_state(p, LMS_USER), &sp->pr_utime);
   3268 	hrt2ts(mstate_aggr_state(p, LMS_SYSTEM), &sp->pr_stime);
   3269 	TICK_TO_TIMESTRUC(p->p_cutime, &sp->pr_cutime);
   3270 	TICK_TO_TIMESTRUC(p->p_cstime, &sp->pr_cstime);
   3271 	(void) strncpy(sp->pr_clname, sclass[t->t_cid].cl_name,
   3272 	    sizeof (sp->pr_clname) - 1);
   3273 	sp->pr_who = t->t_tid;
   3274 	sp->pr_nlwp = p->p_lwpcnt;
   3275 	sp->pr_brkbase = p->p_brkbase;
   3276 	sp->pr_brksize = p->p_brksize;
   3277 	sp->pr_stkbase = prgetstackbase(p);
   3278 	sp->pr_stksize = p->p_stksize;
   3279 	sp->pr_oldcontext = (struct ucontext *)lwp->lwp_oldcontext;
   3280 	sp->pr_processor = t->t_cpu->cpu_id;
   3281 	sp->pr_bind = t->t_bind_cpu;
   3282 
   3283 	/*
   3284 	 * Fetch the current instruction, if not a system process.
   3285 	 * We don't attempt this unless the lwp is stopped.
   3286 	 */
   3287 	if ((p->p_flag & SSYS) || p->p_as == &kas)
   3288 		sp->pr_flags |= (PR_ISSYS|PR_PCINVAL);
   3289 	else if (!(flags & PR_STOPPED))
   3290 		sp->pr_flags |= PR_PCINVAL;
   3291 	else if (!prfetchinstr(lwp, &instr))
   3292 		sp->pr_flags |= PR_PCINVAL;
   3293 	else
   3294 		sp->pr_instr = instr;
   3295 
   3296 	/*
   3297 	 * Drop p_lock while touching the lwp's stack.
   3298 	 */
   3299 	mutex_exit(&p->p_lock);
   3300 	if (prisstep(lwp))
   3301 		sp->pr_flags |= PR_STEP;
   3302 	if ((flags & (PR_STOPPED|PR_ASLEEP)) && t->t_sysnum) {
   3303 		int i;
   3304 		auxv_t *auxp;
   3305 
   3306 		sp->pr_syscall = get_syscall_args(lwp,
   3307 		    (long *)sp->pr_sysarg, &i);
   3308 		sp->pr_nsysarg = (short)i;
   3309 		if (t->t_whystop == PR_SYSEXIT && t->t_sysnum == SYS_execve) {
   3310 			sp->pr_sysarg[0] = 0;
   3311 			sp->pr_sysarg[1] = (uintptr_t)up->u_argv;
   3312 			sp->pr_sysarg[2] = (uintptr_t)up->u_envp;
   3313 			for (i = 0, auxp = up->u_auxv;
   3314 			    i < sizeof (up->u_auxv) / sizeof (up->u_auxv[0]);
   3315 			    i++, auxp++) {
   3316 				if (auxp->a_type == AT_SUN_EXECNAME) {
   3317 					sp->pr_sysarg[0] =
   3318 					    (uintptr_t)auxp->a_un.a_ptr;
   3319 					break;
   3320 				}
   3321 			}
   3322 		}
   3323 	}
   3324 	if ((flags & PR_STOPPED) || t == curthread)
   3325 		prgetprregs(lwp, sp->pr_reg);
   3326 	mutex_enter(&p->p_lock);
   3327 }
   3328 
   3329 /*
   3330  * Return old version of information used by ps(1).
   3331  */
   3332 void
   3333 oprgetpsinfo(proc_t *p, prpsinfo_t *psp, kthread_t *tp)
   3334 {
   3335 	kthread_t *t;
   3336 	char c, state;
   3337 	user_t *up;
   3338 	dev_t d;
   3339 	uint64_t pct;
   3340 	int retval, niceval;
   3341 	cred_t *cred;
   3342 	struct as *as;
   3343 	hrtime_t hrutime, hrstime, cur_time;
   3344 
   3345 	ASSERT(MUTEX_HELD(&p->p_lock));
   3346 
   3347 	bzero(psp, sizeof (*psp));
   3348 
   3349 	if ((t = tp) == NULL)
   3350 		t = prchoose(p);	/* returns locked thread */
   3351 	else
   3352 		thread_lock(t);
   3353 
   3354 	/* kludge: map thread state enum into process state enum */
   3355 
   3356 	if (t == NULL) {
   3357 		state = TS_ZOMB;
   3358 	} else {
   3359 		state = VSTOPPED(t) ? TS_STOPPED : t->t_state;
   3360 		thread_unlock(t);
   3361 	}
   3362 
   3363 	switch (state) {
   3364 	case TS_SLEEP:		state = SSLEEP;		break;
   3365 	case TS_RUN:		state = SRUN;		break;
   3366 	case TS_ONPROC:		state = SONPROC;	break;
   3367 	case TS_ZOMB:		state = SZOMB;		break;
   3368 	case TS_STOPPED:	state = SSTOP;		break;
   3369 	default:		state = 0;		break;
   3370 	}
   3371 	switch (state) {
   3372 	case SSLEEP:	c = 'S';	break;
   3373 	case SRUN:	c = 'R';	break;
   3374 	case SZOMB:	c = 'Z';	break;
   3375 	case SSTOP:	c = 'T';	break;
   3376 	case SIDL:	c = 'I';	break;
   3377 	case SONPROC:	c = 'O';	break;
   3378 #ifdef SXBRK
   3379 	case SXBRK:	c = 'X';	break;
   3380 #endif
   3381 	default:	c = '?';	break;
   3382 	}
   3383 	psp->pr_state = state;
   3384 	psp->pr_sname = c;
   3385 	psp->pr_zomb = (state == SZOMB);
   3386 	/*
   3387 	 * only export SSYS and SMSACCT; everything else is off-limits to
   3388 	 * userland apps.
   3389 	 */
   3390 	psp->pr_flag = p->p_flag & (SSYS | SMSACCT);
   3391 
   3392 	mutex_enter(&p->p_crlock);
   3393 	cred = p->p_cred;
   3394 	psp->pr_uid = crgetruid(cred);
   3395 	psp->pr_gid = crgetrgid(cred);
   3396 	psp->pr_euid = crgetuid(cred);
   3397 	psp->pr_egid = crgetgid(cred);
   3398 	mutex_exit(&p->p_crlock);
   3399 
   3400 	psp->pr_pid = p->p_pid;
   3401 	if (curproc->p_zone->zone_id != GLOBAL_ZONEID &&
   3402 	    (p->p_flag & SZONETOP)) {
   3403 		ASSERT(p->p_zone->zone_id != GLOBAL_ZONEID);
   3404 		/*
   3405 		 * Inside local zones, fake zsched's pid as parent pids for
   3406 		 * processes which reference processes outside of the zone.
   3407 		 */
   3408 		psp->pr_ppid = curproc->p_zone->zone_zsched->p_pid;
   3409 	} else {
   3410 		psp->pr_ppid = p->p_ppid;
   3411 	}
   3412 	psp->pr_pgrp = p->p_pgrp;
   3413 	psp->pr_sid = p->p_sessp->s_sid;
   3414 	psp->pr_addr = prgetpsaddr(p);
   3415 	hrutime = mstate_aggr_state(p, LMS_USER);
   3416 	hrstime = mstate_aggr_state(p, LMS_SYSTEM);
   3417 	hrt2ts(hrutime + hrstime, &psp->pr_time);
   3418 	TICK_TO_TIMESTRUC(p->p_cutime + p->p_cstime, &psp->pr_ctime);
   3419 	switch (p->p_model) {
   3420 	case DATAMODEL_ILP32:
   3421 		psp->pr_dmodel = PR_MODEL_ILP32;
   3422 		break;
   3423 	case DATAMODEL_LP64:
   3424 		psp->pr_dmodel = PR_MODEL_LP64;
   3425 		break;
   3426 	}
   3427 	if (state == SZOMB || t == NULL) {
   3428 		int wcode = p->p_wcode;		/* must be atomic read */
   3429 
   3430 		if (wcode)
   3431 			psp->pr_wstat = wstat(wcode, p->p_wdata);
   3432 		psp->pr_lttydev = PRNODEV;
   3433 		psp->pr_ottydev = (o_dev_t)PRNODEV;
   3434 		psp->pr_size = 0;
   3435 		psp->pr_rssize = 0;
   3436 		psp->pr_pctmem = 0;
   3437 	} else {
   3438 		up = PTOU(p);
   3439 		psp->pr_wchan = t->t_wchan;
   3440 		psp->pr_pri = t->t_pri;
   3441 		(void) strncpy(psp->pr_clname, sclass[t->t_cid].cl_name,
   3442 		    sizeof (psp->pr_clname) - 1);
   3443 		retval = CL_DONICE(t, NULL, 0, &niceval);
   3444 		if (retval == 0) {
   3445 			psp->pr_oldpri = v.v_maxsyspri - psp->pr_pri;
   3446 			psp->pr_nice = niceval + NZERO;
   3447 		} else {
   3448 			psp->pr_oldpri = 0;
   3449 			psp->pr_nice = 0;
   3450 		}
   3451 		d = cttydev(p);
   3452 #ifdef sun
   3453 		{
   3454 			extern dev_t rwsconsdev, rconsdev, uconsdev;
   3455 			/*
   3456 			 * If the controlling terminal is the real
   3457 			 * or workstation console device, map to what the
   3458 			 * user thinks is the console device. Handle case when
   3459 			 * rwsconsdev or rconsdev is set to NODEV for Starfire.
   3460 			 */
   3461 			if ((d == rwsconsdev || d == rconsdev) && d != NODEV)
   3462 				d = uconsdev;
   3463 		}
   3464 #endif
   3465 		psp->pr_lttydev = (d == NODEV) ? PRNODEV : d;
   3466 		psp->pr_ottydev = cmpdev(d);
   3467 		psp->pr_start = up->u_start;
   3468 		bcopy(up->u_comm, psp->pr_fname,
   3469 		    MIN(sizeof (up->u_comm), sizeof (psp->pr_fname)-1));
   3470 		bcopy(up->u_psargs, psp->pr_psargs,
   3471 		    MIN(PRARGSZ-1, PSARGSZ));
   3472 		psp->pr_syscall = t->t_sysnum;
   3473 		psp->pr_argc = up->u_argc;
   3474 		psp->pr_argv = (char **)up->u_argv;
   3475 		psp->pr_envp = (char **)up->u_envp;
   3476 
   3477 		/* compute %cpu for the lwp or process */
   3478 		pct = 0;
   3479 		if ((t = tp) == NULL)
   3480 			t = p->p_tlist;
   3481 		cur_time = gethrtime_unscaled();
   3482 		do {
   3483 			pct += cpu_update_pct(t, cur_time);
   3484 			if (tp != NULL)		/* just do the one lwp */
   3485 				break;
   3486 		} while ((t = t->t_forw) != p->p_tlist);
   3487 
   3488 		psp->pr_pctcpu = prgetpctcpu(pct);
   3489 		psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */
   3490 		if (psp->pr_cpu > 99)
   3491 			psp->pr_cpu = 99;
   3492 
   3493 		if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
   3494 			psp->pr_size = 0;
   3495 			psp->pr_rssize = 0;
   3496 			psp->pr_pctmem = 0;
   3497 		} else {
   3498 			mutex_exit(&p->p_lock);
   3499 			AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
   3500 			psp->pr_size = btopr(as->a_resvsize);
   3501 			psp->pr_rssize = rm_asrss(as);
   3502 			psp->pr_pctmem = rm_pctmemory(as);
   3503 			AS_LOCK_EXIT(as, &as->a_lock);
   3504 			mutex_enter(&p->p_lock);
   3505 		}
   3506 	}
   3507 	psp->pr_bysize = ptob(psp->pr_size);
   3508 	psp->pr_byrssize = ptob(psp->pr_rssize);
   3509 }
   3510 
   3511 /*
   3512  * Return an array of structures with memory map information.
   3513  * We allocate here; the caller must deallocate.
   3514  * The caller is also responsible to append the zero-filled entry
   3515  * that terminates the PIOCMAP output buffer.
   3516  */
   3517 static int
   3518 oprgetmap(proc_t *p, list_t *iolhead)
   3519 {
   3520 	struct as *as = p->p_as;
   3521 	prmap_t *mp;
   3522 	struct seg *seg;
   3523 	struct seg *brkseg, *stkseg;
   3524 	uint_t prot;
   3525 
   3526 	ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
   3527 
   3528 	/*
   3529 	 * Request an initial buffer size that doesn't waste memory
   3530 	 * if the address space has only a small number of segments.
   3531 	 */
   3532 	pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
   3533 
   3534 	if ((seg = AS_SEGFIRST(as)) == NULL)
   3535 		return (0);
   3536 
   3537 	brkseg = break_seg(p);
   3538 	stkseg = as_segat(as, prgetstackbase(p));
   3539 
   3540 	do {
   3541 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
   3542 		caddr_t saddr, naddr;
   3543 		void *tmp = NULL;
   3544 
   3545 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
   3546 			prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
   3547 			if (saddr == naddr)
   3548 				continue;
   3549 
   3550 			mp = pr_iol_newbuf(iolhead, sizeof (*mp));
   3551 
   3552 			mp->pr_vaddr = saddr;
   3553 			mp->pr_size = naddr - saddr;
   3554 			mp->pr_off = SEGOP_GETOFFSET(seg, saddr);
   3555 			mp->pr_mflags = 0;
   3556 			if (prot & PROT_READ)
   3557 				mp->pr_mflags |= MA_READ;
   3558 			if (prot & PROT_WRITE)
   3559 				mp->pr_mflags |= MA_WRITE;
   3560 			if (prot & PROT_EXEC)
   3561 				mp->pr_mflags |= MA_EXEC;
   3562 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
   3563 				mp->pr_mflags |= MA_SHARED;
   3564 			if (seg == brkseg)
   3565 				mp->pr_mflags |= MA_BREAK;
   3566 			else if (seg == stkseg)
   3567 				mp->pr_mflags |= MA_STACK;
   3568 			mp->pr_pagesize = PAGESIZE;
   3569 		}
   3570 		ASSERT(tmp == NULL);
   3571 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
   3572 
   3573 	return (0);
   3574 }
   3575 
   3576 #ifdef _SYSCALL32_IMPL
   3577 static int
   3578 oprgetmap32(proc_t *p, list_t *iolhead)
   3579 {
   3580 	struct as *as = p->p_as;
   3581 	ioc_prmap32_t *mp;
   3582 	struct seg *seg;
   3583 	struct seg *brkseg, *stkseg;
   3584 	uint_t prot;
   3585 
   3586 	ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
   3587 
   3588 	/*
   3589 	 * Request an initial buffer size that doesn't waste memory
   3590 	 * if the address space has only a small number of segments.
   3591 	 */
   3592 	pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
   3593 
   3594 	if ((seg = AS_SEGFIRST(as)) == NULL)
   3595 		return (0);
   3596 
   3597 	brkseg = break_seg(p);
   3598 	stkseg = as_segat(as, prgetstackbase(p));
   3599 
   3600 	do {
   3601 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
   3602 		caddr_t saddr, naddr;
   3603 		void *tmp = NULL;
   3604 
   3605 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
   3606 			prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
   3607 			if (saddr == naddr)
   3608 				continue;
   3609 
   3610 			mp = pr_iol_newbuf(iolhead, sizeof (*mp));
   3611 
   3612 			mp->pr_vaddr = (caddr32_t)(uintptr_t)saddr;
   3613 			mp->pr_size = (size32_t)(naddr - saddr);
   3614 			mp->pr_off = (off32_t)SEGOP_GETOFFSET(seg, saddr);
   3615 			mp->pr_mflags = 0;
   3616 			if (prot & PROT_READ)
   3617 				mp->pr_mflags |= MA_READ;
   3618 			if (prot & PROT_WRITE)
   3619 				mp->pr_mflags |= MA_WRITE;
   3620 			if (prot & PROT_EXEC)
   3621 				mp->pr_mflags |= MA_EXEC;
   3622 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
   3623 				mp->pr_mflags |= MA_SHARED;
   3624 			if (seg == brkseg)
   3625 				mp->pr_mflags |= MA_BREAK;
   3626 			else if (seg == stkseg)
   3627 				mp->pr_mflags |= MA_STACK;
   3628 			mp->pr_pagesize = PAGESIZE;
   3629 		}
   3630 		ASSERT(tmp == NULL);
   3631 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
   3632 
   3633 	return (0);
   3634 }
   3635 #endif	/* _SYSCALL32_IMPL */
   3636 
   3637 /*
   3638  * Return the size of the old /proc page data file.
   3639  */
   3640 size_t
   3641 oprpdsize(struct as *as)
   3642 {
   3643 	struct seg *seg;
   3644 	size_t size;
   3645 
   3646 	ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
   3647 
   3648 	if ((seg = AS_SEGFIRST(as)) == NULL)
   3649 		return (0);
   3650 
   3651 	size = sizeof (prpageheader_t);
   3652 	do {
   3653 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
   3654 		caddr_t saddr, naddr;
   3655 		void *tmp = NULL;
   3656 		size_t npage;
   3657 
   3658 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
   3659 			(void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
   3660 			if ((npage = (naddr - saddr) / PAGESIZE) != 0)
   3661 				size += sizeof (prasmap_t) + roundlong(npage);
   3662 		}
   3663 		ASSERT(tmp == NULL);
   3664 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
   3665 
   3666 	return (size);
   3667 }
   3668 
   3669 #ifdef _SYSCALL32_IMPL
   3670 size_t
   3671 oprpdsize32(struct as *as)
   3672 {
   3673 	struct seg *seg;
   3674 	size_t size;
   3675 
   3676 	ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
   3677 
   3678 	if ((seg = AS_SEGFIRST(as)) == NULL)
   3679 		return (0);
   3680 
   3681 	size = sizeof (ioc_prpageheader32_t);
   3682 	do {
   3683 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
   3684 		caddr_t saddr, naddr;
   3685 		void *tmp = NULL;
   3686 		size_t npage;
   3687 
   3688 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
   3689 			(void) pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
   3690 			if ((npage = (naddr - saddr) / PAGESIZE) != 0)
   3691 				size += sizeof (ioc_prmap32_t) + round4(npage);
   3692 		}
   3693 		ASSERT(tmp == NULL);
   3694 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
   3695 
   3696 	return (size);
   3697 }
   3698 #endif	/* _SYSCALL32_IMPL */
   3699 
   3700 /*
   3701  * Read old /proc page data information.
   3702  */
   3703 int
   3704 oprpdread(struct as *as, uint_t hatid, struct uio *uiop)
   3705 {
   3706 	caddr_t buf;
   3707 	size_t size;
   3708 	prpageheader_t *php;
   3709 	prasmap_t *pmp;
   3710 	struct seg *seg;
   3711 	int error;
   3712 
   3713 again:
   3714 	AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
   3715 
   3716 	if ((seg = AS_SEGFIRST(as)) == NULL) {
   3717 		AS_LOCK_EXIT(as, &as->a_lock);
   3718 		return (0);
   3719 	}
   3720 	size = oprpdsize(as);
   3721 	if (uiop->uio_resid < size) {
   3722 		AS_LOCK_EXIT(as, &as->a_lock);
   3723 		return (E2BIG);
   3724 	}
   3725 
   3726 	buf = kmem_zalloc(size, KM_SLEEP);
   3727 	php = (prpageheader_t *)buf;
   3728 	pmp = (prasmap_t *)(buf + sizeof (prpageheader_t));
   3729 
   3730 	hrt2ts(gethrtime(), &php->pr_tstamp);
   3731 	php->pr_nmap = 0;
   3732 	php->pr_npage = 0;
   3733 	do {
   3734 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
   3735 		caddr_t saddr, naddr;
   3736 		void *tmp = NULL;
   3737 
   3738 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
   3739 			size_t len;
   3740 			size_t npage;
   3741 			uint_t prot;
   3742 			uintptr_t next;
   3743 
   3744 			prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
   3745 			if ((len = naddr - saddr) == 0)
   3746 				continue;
   3747 			npage = len / PAGESIZE;
   3748 			next = (uintptr_t)(pmp + 1) + roundlong(npage);
   3749 			/*
   3750 			 * It's possible that the address space can change
   3751 			 * subtlely even though we're holding as->a_lock
   3752 			 * due to the nondeterminism of page_exists() in
   3753 			 * the presence of asychronously flushed pages or
   3754 			 * mapped files whose sizes are changing.
   3755 			 * page_exists() may be called indirectly from
   3756 			 * pr_getprot() by a SEGOP_INCORE() routine.
   3757 			 * If this happens we need to make sure we don't
   3758 			 * overrun the buffer whose size we computed based
   3759 			 * on the initial iteration through the segments.
   3760 			 * Once we've detected an overflow, we need to clean
   3761 			 * up the temporary memory allocated in pr_getprot()
   3762 			 * and retry. If there's a pending signal, we return
   3763 			 * EINTR so that this thread can be dislodged if
   3764 			 * a latent bug causes us to spin indefinitely.
   3765 			 */
   3766 			if (next > (uintptr_t)buf + size) {
   3767 				pr_getprot_done(&tmp);
   3768 				AS_LOCK_EXIT(as, &as->a_lock);
   3769 
   3770 				kmem_free(buf, size);
   3771 
   3772 				if (ISSIG(curthread, JUSTLOOKING))
   3773 					return (EINTR);
   3774 
   3775 				goto again;
   3776 			}
   3777 
   3778 			php->pr_nmap++;
   3779 			php->pr_npage += npage;
   3780 			pmp->pr_vaddr = saddr;
   3781 			pmp->pr_npage = npage;
   3782 			pmp->pr_off = SEGOP_GETOFFSET(seg, saddr);
   3783 			pmp->pr_mflags = 0;
   3784 			if (prot & PROT_READ)
   3785 				pmp->pr_mflags |= MA_READ;
   3786 			if (prot & PROT_WRITE)
   3787 				pmp->pr_mflags |= MA_WRITE;
   3788 			if (prot & PROT_EXEC)
   3789 				pmp->pr_mflags |= MA_EXEC;
   3790 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
   3791 				pmp->pr_mflags |= MA_SHARED;
   3792 			pmp->pr_pagesize = PAGESIZE;
   3793 			hat_getstat(as, saddr, len, hatid,
   3794 			    (char *)(pmp + 1), HAT_SYNC_ZERORM);
   3795 			pmp = (prasmap_t *)next;
   3796 		}
   3797 		ASSERT(tmp == NULL);
   3798 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
   3799 
   3800 	AS_LOCK_EXIT(as, &as->a_lock);
   3801 
   3802 	ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
   3803 	error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
   3804 	kmem_free(buf, size);
   3805 
   3806 	return (error);
   3807 }
   3808 
   3809 #ifdef _SYSCALL32_IMPL
   3810 int
   3811 oprpdread32(struct as *as, uint_t hatid, struct uio *uiop)
   3812 {
   3813 	caddr_t buf;
   3814 	size_t size;
   3815 	ioc_prpageheader32_t *php;
   3816 	ioc_prasmap32_t *pmp;
   3817 	struct seg *seg;
   3818 	int error;
   3819 
   3820 again:
   3821 	AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
   3822 
   3823 	if ((seg = AS_SEGFIRST(as)) == NULL) {
   3824 		AS_LOCK_EXIT(as, &as->a_lock);
   3825 		return (0);
   3826 	}
   3827 	size = oprpdsize32(as);
   3828 	if (uiop->uio_resid < size) {
   3829 		AS_LOCK_EXIT(as, &as->a_lock);
   3830 		return (E2BIG);
   3831 	}
   3832 
   3833 	buf = kmem_zalloc(size, KM_SLEEP);
   3834 	php = (ioc_prpageheader32_t *)buf;
   3835 	pmp = (ioc_prasmap32_t *)(buf + sizeof (ioc_prpageheader32_t));
   3836 
   3837 	hrt2ts32(gethrtime(), &php->pr_tstamp);
   3838 	php->pr_nmap = 0;
   3839 	php->pr_npage = 0;
   3840 	do {
   3841 		caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
   3842 		caddr_t saddr, naddr;
   3843 		void *tmp = NULL;
   3844 
   3845 		for (saddr = seg->s_base; saddr < eaddr; saddr = naddr) {
   3846 			size_t len;
   3847 			size_t npage;
   3848 			uint_t prot;
   3849 			uintptr_t next;
   3850 
   3851 			prot = pr_getprot(seg, 0, &tmp, &saddr, &naddr, eaddr);
   3852 			if ((len = naddr - saddr) == 0)
   3853 				continue;
   3854 			npage = len / PAGESIZE;
   3855 			next = (uintptr_t)(pmp + 1) + round4(npage);
   3856 			/*
   3857 			 * It's possible that the address space can change
   3858 			 * subtlely even though we're holding as->a_lock
   3859 			 * due to the nondeterminism of page_exists() in
   3860 			 * the presence of asychronously flushed pages or
   3861 			 * mapped files whose sizes are changing.
   3862 			 * page_exists() may be called indirectly from
   3863 			 * pr_getprot() by a SEGOP_INCORE() routine.
   3864 			 * If this happens we need to make sure we don't
   3865 			 * overrun the buffer whose size we computed based
   3866 			 * on the initial iteration through the segments.
   3867 			 * Once we've detected an overflow, we need to clean
   3868 			 * up the temporary memory allocated in pr_getprot()
   3869 			 * and retry. If there's a pending signal, we return
   3870 			 * EINTR so that this thread can be dislodged if
   3871 			 * a latent bug causes us to spin indefinitely.
   3872 			 */
   3873 			if (next > (uintptr_t)buf + size) {
   3874 				pr_getprot_done(&tmp);
   3875 				AS_LOCK_EXIT(as, &as->a_lock);
   3876 
   3877 				kmem_free(buf, size);
   3878 
   3879 				if (ISSIG(curthread, JUSTLOOKING))
   3880 					return (EINTR);
   3881 
   3882 				goto again;
   3883 			}
   3884 
   3885 			php->pr_nmap++;
   3886 			php->pr_npage += npage;
   3887 			pmp->pr_vaddr = (uint32_t)(uintptr_t)saddr;
   3888 			pmp->pr_npage = (uint32_t)npage;
   3889 			pmp->pr_off = (int32_t)SEGOP_GETOFFSET(seg, saddr);
   3890 			pmp->pr_mflags = 0;
   3891 			if (prot & PROT_READ)
   3892 				pmp->pr_mflags |= MA_READ;
   3893 			if (prot & PROT_WRITE)
   3894 				pmp->pr_mflags |= MA_WRITE;
   3895 			if (prot & PROT_EXEC)
   3896 				pmp->pr_mflags |= MA_EXEC;
   3897 			if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
   3898 				pmp->pr_mflags |= MA_SHARED;
   3899 			pmp->pr_pagesize = PAGESIZE;
   3900 			hat_getstat(as, saddr, len, hatid,
   3901 			    (char *)(pmp + 1), HAT_SYNC_ZERORM);
   3902 			pmp = (ioc_prasmap32_t *)next;
   3903 		}
   3904 		ASSERT(tmp == NULL);
   3905 	} while ((seg = AS_SEGNEXT(as, seg)) != NULL);
   3906 
   3907 	AS_LOCK_EXIT(as, &as->a_lock);
   3908 
   3909 	ASSERT((uintptr_t)pmp == (uintptr_t)buf + size);
   3910 	error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
   3911 	kmem_free(buf, size);
   3912 
   3913 	return (error);
   3914 }
   3915 #endif	/* _SYSCALL32_IMPL */
   3916 
   3917 /*ARGSUSED*/
   3918 #ifdef _SYSCALL32_IMPL
   3919 int
   3920 prioctl(
   3921 	struct vnode *vp,
   3922 	int cmd,
   3923 	intptr_t arg,
   3924 	int flag,
   3925 	cred_t *cr,
   3926 	int *rvalp,
   3927 	caller_context_t *ct)
   3928 {
   3929 	switch (curproc->p_model) {
   3930 	case DATAMODEL_ILP32:
   3931 		return (prioctl32(vp, cmd, arg, flag, cr, rvalp, ct));
   3932 	case DATAMODEL_LP64:
   3933 		return (prioctl64(vp, cmd, arg, flag, cr, rvalp, ct));
   3934 	default:
   3935 		return (ENOSYS);
   3936 	}
   3937 }
   3938 #endif	/* _SYSCALL32_IMPL */
   3939