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  * Copyright 2019 Joyent, Inc.
  26  */
  27 
  28 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  29 /*        All rights reserved.  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/param.h>
  33 #include <sys/vmparam.h>
  34 #include <sys/var.h>
  35 #include <sys/cmn_err.h>
  36 #include <sys/cred.h>
  37 #include <sys/debug.h>
  38 #include <sys/errno.h>
  39 #include <sys/file.h>
  40 #include <sys/inline.h>
  41 #include <sys/kmem.h>
  42 #include <sys/proc.h>
  43 #include <sys/brand.h>
  44 #include <sys/sysmacros.h>
  45 #include <sys/systm.h>
 
 
 192          * Support for old /proc interface.
 193          */
 194         if (pnp->pr_pidfile != NULL) {
 195                 ASSERT(pnp->pr_type == PR_PIDDIR);
 196                 vp = pnp->pr_pidfile;
 197                 pnp = VTOP(vp);
 198                 ASSERT(pnp->pr_type == PR_PIDFILE);
 199         }
 200 
 201         if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
 202                 return (ENOTTY);
 203 
 204         /*
 205          * Fail ioctls which are logically "write" requests unless
 206          * the user has write permission.
 207          */
 208         if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
 209                 return (EBADF);
 210 
 211         /*
 212          * Perform any necessary copyin() operations before
 213          * locking the process.  Helps avoid deadlocks and
 214          * improves performance.
 215          *
 216          * Also, detect invalid ioctl codes here to avoid
 217          * locking a process unnnecessarily.
 218          *
 219          * Also, prepare to allocate space that will be needed below,
 220          * case by case.
 221          */
 222         error = 0;
 223         switch (cmd) {
 224         case PIOCGETPR:
 225                 thingsize = sizeof (proc_t);
 226                 break;
 227         case PIOCGETU:
 228                 thingsize = sizeof (user_t);
 229                 break;
 230         case PIOCSTOP:
 231         case PIOCWSTOP:
 232         case PIOCLWPIDS:
 233         case PIOCGTRACE:
 234         case PIOCGENTRY:
 235         case PIOCGEXIT:
 236         case PIOCSRLC:
 237         case PIOCRRLC:
 238         case PIOCSFORK:
 239         case PIOCRFORK:
 240         case PIOCGREG:
 241         case PIOCGFPREG:
 242         case PIOCSTATUS:
 243         case PIOCLSTATUS:
 244         case PIOCPSINFO:
 245         case PIOCMAXSIG:
 246         case PIOCGXREGSIZE:
 247                 break;
 248         case PIOCSXREG:         /* set extra registers */
 249         case PIOCGXREG:         /* get extra registers */
 250 #if defined(__sparc)
 251                 thingsize = sizeof (prxregset_t);
 252 #else
 253                 thingsize = 0;
 254 #endif
 255                 break;
 256         case PIOCACTION:
 257                 thingsize = (nsig-1) * sizeof (struct sigaction);
 258                 break;
 259         case PIOCGHOLD:
 260         case PIOCNMAP:
 261         case PIOCMAP:
 262         case PIOCGFAULT:
 263         case PIOCCFAULT:
 264         case PIOCCRED:
 265         case PIOCGROUPS:
 266         case PIOCUSAGE:
 267         case PIOCLUSAGE:
 268                 break;
 269         case PIOCOPENPD:
 270                 /*
 271                  * We will need this below.
 272                  * Allocate it now, before locking the process.
 273                  */
 274                 xpnp = prgetnode(vp, PR_OPAGEDATA);
 
 375         /*
 376          * If we need kmem_alloc()d space then we allocate it now, before
 377          * grabbing the process lock.  Using kmem_alloc(KM_SLEEP) while
 378          * holding the process lock leads to deadlock with the clock thread.
 379          * (The clock thread wakes up the pageout daemon to free up space.
 380          * If the clock thread blocks behind us and we are sleeping waiting
 381          * for space, then space may never become available.)
 382          */
 383         if (thingsize) {
 384                 ASSERT(thing == NULL);
 385                 thing = kmem_alloc(thingsize, KM_SLEEP);
 386         }
 387 
 388         switch (cmd) {
 389         case PIOCPSINFO:
 390         case PIOCGETPR:
 391         case PIOCUSAGE:
 392         case PIOCLUSAGE:
 393                 zdisp = ZYES;
 394                 break;
 395         case PIOCSXREG:         /* set extra registers */
 396                 /*
 397                  * perform copyin before grabbing the process lock
 398                  */
 399                 if (thing) {
 400                         if (copyin(cmaddr, thing, thingsize)) {
 401                                 kmem_free(thing, thingsize);
 402                                 return (EFAULT);
 403                         }
 404                 }
 405                 /* fall through... */
 406         default:
 407                 zdisp = ZNO;
 408                 break;
 409         }
 410 
 411         if ((error = prlock(pnp, zdisp)) != 0) {
 412                 if (thing != NULL)
 413                         kmem_free(thing, thingsize);
 414                 if (xpnp)
 415                         prfreenode(xpnp);
 416                 return (error);
 417         }
 418 
 419         pcp = pnp->pr_common;
 420         p = pcp->prc_proc;
 421         ASSERT(p != NULL);
 422 
 423         /*
 424          * Choose a thread/lwp for the operation.
 425          */
 
 772                 if (copyout(&un.fpregs, cmaddr, sizeof (un.fpregs)))
 773                         error = EFAULT;
 774                 break;
 775 
 776         case PIOCSFPREG:        /* set floating-point registers */
 777                 if (!prhasfp())
 778                         error = EINVAL; /* No FP support */
 779                 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
 780                         error = EBUSY;
 781                 else {
 782                         /* drop p_lock while touching the lwp's stack */
 783                         mutex_exit(&p->p_lock);
 784                         prsetprfpregs(lwp, &un.fpregs);
 785                         mutex_enter(&p->p_lock);
 786                 }
 787                 prunlock(pnp);
 788                 break;
 789 
 790         case PIOCGXREGSIZE:     /* get the size of the extra registers */
 791         {
 792                 int xregsize;
 793 
 794                 if (prhasx(p)) {
 795                         xregsize = prgetprxregsize(p);
 796                         prunlock(pnp);
 797                         if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
 798                                 error = EFAULT;
 799                 } else {
 800                         prunlock(pnp);
 801                         error = EINVAL; /* No extra register support */
 802                 }
 803                 break;
 804         }
 805 
 806         case PIOCGXREG:         /* get extra registers */
 807                 if (prhasx(p)) {
 808                         bzero(thing, thingsize);
 809                         if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
 810                                 /* drop p_lock to touch the stack */
 811                                 mutex_exit(&p->p_lock);
 812                                 prgetprxregs(lwp, thing);
 813                                 mutex_enter(&p->p_lock);
 814                         }
 815                         prunlock(pnp);
 816                         if (copyout(thing, cmaddr, thingsize))
 817                                 error = EFAULT;
 818                 } else {
 819                         prunlock(pnp);
 820                         error = EINVAL; /* No extra register support */
 821                 }
 822                 if (thing) {
 823                         kmem_free(thing, thingsize);
 824                         thing = NULL;
 825                 }
 826                 break;
 827 
 828         case PIOCSXREG:         /* set extra registers */
 829                 if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
 830                         error = EBUSY;
 831                 else if (!prhasx(p))
 832                         error = EINVAL; /* No extra register support */
 833                 else if (thing) {
 834                         /* drop p_lock while touching the lwp's stack */
 835                         mutex_exit(&p->p_lock);
 836                         prsetprxregs(lwp, thing);
 837                         mutex_enter(&p->p_lock);
 838                 }
 839                 prunlock(pnp);
 840                 if (thing) {
 841                         kmem_free(thing, thingsize);
 842                         thing = NULL;
 843                 }
 844                 break;
 845 
 846         case PIOCSTATUS:        /* get process/lwp status */
 847                 oprgetstatus(t, &un.prstat, VTOZONE(vp));
 848                 prunlock(pnp);
 849                 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
 850                         error = EFAULT;
 851                 break;
 852 
 853         case PIOCLSTATUS:       /* get status for process & all lwps */
 854         {
 855                 int Nlwp;
 856                 int nlwp;
 857                 prstatus_t *Bprsp;
 858                 prstatus_t *prsp;
 859 
 860                 nlwp = Nlwp = p->p_lwpcnt;
 861 
 862                 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus_t)) {
 863                         kmem_free(thing, thingsize);
 864                         thing = NULL;
 865                 }
 
1747          * Support for old /proc interface.
1748          */
1749         if (pnp->pr_pidfile != NULL) {
1750                 ASSERT(pnp->pr_type == PR_PIDDIR);
1751                 vp = pnp->pr_pidfile;
1752                 pnp = VTOP(vp);
1753                 ASSERT(pnp->pr_type == PR_PIDFILE);
1754         }
1755 
1756         if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
1757                 return (ENOTTY);
1758 
1759         /*
1760          * Fail ioctls which are logically "write" requests unless
1761          * the user has write permission.
1762          */
1763         if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
1764                 return (EBADF);
1765 
1766         /*
1767          * Perform any necessary copyin() operations before
1768          * locking the process.  Helps avoid deadlocks and
1769          * improves performance.
1770          *
1771          * Also, detect invalid ioctl codes here to avoid
1772          * locking a process unnnecessarily.
1773          *
1774          * Also, prepare to allocate space that will be needed below,
1775          * case by case.
1776          */
1777         error = 0;
1778         switch (cmd) {
1779         case PIOCGETPR:
1780                 thingsize = sizeof (proc_t);
1781                 break;
1782         case PIOCGETU:
1783                 thingsize = sizeof (user_t);
1784                 break;
1785         case PIOCSTOP:
1786         case PIOCWSTOP:
1787         case PIOCLWPIDS:
1788         case PIOCGTRACE:
1789         case PIOCGENTRY:
1790         case PIOCGEXIT:
1791         case PIOCSRLC:
1792         case PIOCRRLC:
1793         case PIOCSFORK:
1794         case PIOCRFORK:
1795         case PIOCGREG:
1796         case PIOCGFPREG:
1797         case PIOCSTATUS:
1798         case PIOCLSTATUS:
1799         case PIOCPSINFO:
1800         case PIOCMAXSIG:
1801         case PIOCGXREGSIZE:
1802                 break;
1803         case PIOCSXREG:         /* set extra registers */
1804         case PIOCGXREG:         /* get extra registers */
1805 #if defined(__sparc)
1806                 thingsize = sizeof (prxregset_t);
1807 #else
1808                 thingsize = 0;
1809 #endif
1810                 break;
1811         case PIOCACTION:
1812                 thingsize = (nsig-1) * sizeof (struct sigaction32);
1813                 break;
1814         case PIOCGHOLD:
1815         case PIOCNMAP:
1816         case PIOCMAP:
1817         case PIOCGFAULT:
1818         case PIOCCFAULT:
1819         case PIOCCRED:
1820         case PIOCGROUPS:
1821         case PIOCUSAGE:
1822         case PIOCLUSAGE:
1823                 break;
1824         case PIOCOPENPD:
1825                 /*
1826                  * We will need this below.
1827                  * Allocate it now, before locking the process.
1828                  */
1829                 xpnp = prgetnode(vp, PR_OPAGEDATA);
 
1930         /*
1931          * If we need kmem_alloc()d space then we allocate it now, before
1932          * grabbing the process lock.  Using kmem_alloc(KM_SLEEP) while
1933          * holding the process lock leads to deadlock with the clock thread.
1934          * (The clock thread wakes up the pageout daemon to free up space.
1935          * If the clock thread blocks behind us and we are sleeping waiting
1936          * for space, then space may never become available.)
1937          */
1938         if (thingsize) {
1939                 ASSERT(thing == NULL);
1940                 thing = kmem_alloc(thingsize, KM_SLEEP);
1941         }
1942 
1943         switch (cmd) {
1944         case PIOCPSINFO:
1945         case PIOCGETPR:
1946         case PIOCUSAGE:
1947         case PIOCLUSAGE:
1948                 zdisp = ZYES;
1949                 break;
1950         case PIOCSXREG:         /* set extra registers */
1951                 /*
1952                  * perform copyin before grabbing the process lock
1953                  */
1954                 if (thing) {
1955                         if (copyin(cmaddr, thing, thingsize)) {
1956                                 kmem_free(thing, thingsize);
1957                                 return (EFAULT);
1958                         }
1959                 }
1960                 /* fall through... */
1961         default:
1962                 zdisp = ZNO;
1963                 break;
1964         }
1965 
1966         if ((error = prlock(pnp, zdisp)) != 0) {
1967                 if (thing != NULL)
1968                         kmem_free(thing, thingsize);
1969                 if (xpnp)
1970                         prfreenode(xpnp);
1971                 return (error);
1972         }
1973 
1974         pcp = pnp->pr_common;
1975         p = pcp->prc_proc;
1976         ASSERT(p != NULL);
1977 
1978         /*
1979          * Choose a thread/lwp for the operation.
1980          */
 
2367                 break;
2368 
2369         case PIOCSFPREG:        /* set floating-point registers */
2370                 if (!prhasfp())
2371                         error = EINVAL; /* No FP support */
2372                 else if (PROCESS_NOT_32BIT(p))
2373                         error = EOVERFLOW;
2374                 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
2375                         error = EBUSY;
2376                 else {
2377                         /* drop p_lock while touching the lwp's stack */
2378                         mutex_exit(&p->p_lock);
2379                         prsetprfpregs32(lwp, &un32.fpregs);
2380                         mutex_enter(&p->p_lock);
2381                 }
2382                 prunlock(pnp);
2383                 break;
2384 
2385         case PIOCGXREGSIZE:     /* get the size of the extra registers */
2386         {
2387                 int xregsize;
2388 
2389                 if (prhasx(p)) {
2390                         xregsize = prgetprxregsize(p);
2391                         prunlock(pnp);
2392                         if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
2393                                 error = EFAULT;
2394                 } else {
2395                         prunlock(pnp);
2396                         error = EINVAL; /* No extra register support */
2397                 }
2398                 break;
2399         }
2400 
2401         case PIOCGXREG:         /* get extra registers */
2402                 if (PROCESS_NOT_32BIT(p))
2403                         error = EOVERFLOW;
2404                 else if (!prhasx(p))
2405                         error = EINVAL; /* No extra register support */
2406                 else {
2407                         bzero(thing, thingsize);
2408                         if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
2409                                 /* drop p_lock to touch the stack */
2410                                 mutex_exit(&p->p_lock);
2411                                 prgetprxregs(lwp, thing);
2412                                 mutex_enter(&p->p_lock);
2413                         }
2414                 }
2415                 prunlock(pnp);
2416                 if (error == 0 &&
2417                     copyout(thing, cmaddr, thingsize))
2418                         error = EFAULT;
2419                 if (thing) {
2420                         kmem_free(thing, thingsize);
2421                         thing = NULL;
2422                 }
2423                 break;
2424 
2425         case PIOCSXREG:         /* set extra registers */
2426                 if (PROCESS_NOT_32BIT(p))
2427                         error = EOVERFLOW;
2428                 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
2429                         error = EBUSY;
2430                 else if (!prhasx(p))
2431                         error = EINVAL; /* No extra register support */
2432                 else if (thing) {
2433                         /* drop p_lock while touching the lwp's stack */
2434                         mutex_exit(&p->p_lock);
2435                         prsetprxregs(lwp, thing);
2436                         mutex_enter(&p->p_lock);
2437                 }
2438                 prunlock(pnp);
2439                 if (thing) {
2440                         kmem_free(thing, thingsize);
2441                         thing = NULL;
2442                 }
2443                 break;
2444 
2445         case PIOCSTATUS:        /* get process/lwp status */
2446                 if (PROCESS_NOT_32BIT(p)) {
2447                         prunlock(pnp);
2448                         error = EOVERFLOW;
2449                         break;
2450                 }
2451                 oprgetstatus32(t, &un32.prstat, VTOZONE(vp));
2452                 prunlock(pnp);
2453                 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat)))
2454                         error = EFAULT;
2455                 break;
2456 
2457         case PIOCLSTATUS:       /* get status for process & all lwps */
2458         {
2459                 int Nlwp;
2460                 int nlwp;
 
 | 
 
 
   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  * Copyright 2019 Joyent, Inc.
  26  * Copyright 2023 Oxide Computer Company
  27  */
  28 
  29 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  30 /*        All rights reserved.  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/param.h>
  34 #include <sys/vmparam.h>
  35 #include <sys/var.h>
  36 #include <sys/cmn_err.h>
  37 #include <sys/cred.h>
  38 #include <sys/debug.h>
  39 #include <sys/errno.h>
  40 #include <sys/file.h>
  41 #include <sys/inline.h>
  42 #include <sys/kmem.h>
  43 #include <sys/proc.h>
  44 #include <sys/brand.h>
  45 #include <sys/sysmacros.h>
  46 #include <sys/systm.h>
 
 
 193          * Support for old /proc interface.
 194          */
 195         if (pnp->pr_pidfile != NULL) {
 196                 ASSERT(pnp->pr_type == PR_PIDDIR);
 197                 vp = pnp->pr_pidfile;
 198                 pnp = VTOP(vp);
 199                 ASSERT(pnp->pr_type == PR_PIDFILE);
 200         }
 201 
 202         if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
 203                 return (ENOTTY);
 204 
 205         /*
 206          * Fail ioctls which are logically "write" requests unless
 207          * the user has write permission.
 208          */
 209         if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
 210                 return (EBADF);
 211 
 212         /*
 213          * The following commands are no longer supported. They were present on
 214          * SPARC and were always errors on other platforms. We now explicitly
 215          * return ENOTSUP to indicate that this is no longer done.
 216          */
 217         switch (cmd) {
 218         case PIOCSXREG:
 219                 return (ENOTSUP);
 220         default:
 221                 break;
 222         }
 223 
 224         /*
 225          * Perform any necessary copyin() operations before
 226          * locking the process.  Helps avoid deadlocks and
 227          * improves performance.
 228          *
 229          * Also, detect invalid ioctl codes here to avoid
 230          * locking a process unnecessarily.
 231          *
 232          * Also, prepare to allocate space that will be needed below,
 233          * case by case.
 234          */
 235         error = 0;
 236         switch (cmd) {
 237         case PIOCGETPR:
 238                 thingsize = sizeof (proc_t);
 239                 break;
 240         case PIOCGETU:
 241                 thingsize = sizeof (user_t);
 242                 break;
 243         case PIOCSTOP:
 244         case PIOCWSTOP:
 245         case PIOCLWPIDS:
 246         case PIOCGTRACE:
 247         case PIOCGENTRY:
 248         case PIOCGEXIT:
 249         case PIOCSRLC:
 250         case PIOCRRLC:
 251         case PIOCSFORK:
 252         case PIOCRFORK:
 253         case PIOCGREG:
 254         case PIOCGFPREG:
 255         case PIOCSTATUS:
 256         case PIOCLSTATUS:
 257         case PIOCPSINFO:
 258         case PIOCMAXSIG:
 259         case PIOCGXREGSIZE:
 260                 break;
 261         case PIOCGXREG:         /* get extra registers */
 262                 thingsize = prgetprxregsize(p);
 263                 break;
 264         case PIOCACTION:
 265                 thingsize = (nsig-1) * sizeof (struct sigaction);
 266                 break;
 267         case PIOCGHOLD:
 268         case PIOCNMAP:
 269         case PIOCMAP:
 270         case PIOCGFAULT:
 271         case PIOCCFAULT:
 272         case PIOCCRED:
 273         case PIOCGROUPS:
 274         case PIOCUSAGE:
 275         case PIOCLUSAGE:
 276                 break;
 277         case PIOCOPENPD:
 278                 /*
 279                  * We will need this below.
 280                  * Allocate it now, before locking the process.
 281                  */
 282                 xpnp = prgetnode(vp, PR_OPAGEDATA);
 
 383         /*
 384          * If we need kmem_alloc()d space then we allocate it now, before
 385          * grabbing the process lock.  Using kmem_alloc(KM_SLEEP) while
 386          * holding the process lock leads to deadlock with the clock thread.
 387          * (The clock thread wakes up the pageout daemon to free up space.
 388          * If the clock thread blocks behind us and we are sleeping waiting
 389          * for space, then space may never become available.)
 390          */
 391         if (thingsize) {
 392                 ASSERT(thing == NULL);
 393                 thing = kmem_alloc(thingsize, KM_SLEEP);
 394         }
 395 
 396         switch (cmd) {
 397         case PIOCPSINFO:
 398         case PIOCGETPR:
 399         case PIOCUSAGE:
 400         case PIOCLUSAGE:
 401                 zdisp = ZYES;
 402                 break;
 403         default:
 404                 zdisp = ZNO;
 405                 break;
 406         }
 407 
 408         if ((error = prlock(pnp, zdisp)) != 0) {
 409                 if (thing != NULL)
 410                         kmem_free(thing, thingsize);
 411                 if (xpnp)
 412                         prfreenode(xpnp);
 413                 return (error);
 414         }
 415 
 416         pcp = pnp->pr_common;
 417         p = pcp->prc_proc;
 418         ASSERT(p != NULL);
 419 
 420         /*
 421          * Choose a thread/lwp for the operation.
 422          */
 
 769                 if (copyout(&un.fpregs, cmaddr, sizeof (un.fpregs)))
 770                         error = EFAULT;
 771                 break;
 772 
 773         case PIOCSFPREG:        /* set floating-point registers */
 774                 if (!prhasfp())
 775                         error = EINVAL; /* No FP support */
 776                 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
 777                         error = EBUSY;
 778                 else {
 779                         /* drop p_lock while touching the lwp's stack */
 780                         mutex_exit(&p->p_lock);
 781                         prsetprfpregs(lwp, &un.fpregs);
 782                         mutex_enter(&p->p_lock);
 783                 }
 784                 prunlock(pnp);
 785                 break;
 786 
 787         case PIOCGXREGSIZE:     /* get the size of the extra registers */
 788         {
 789                 if (prhasx(p)) {
 790                         size_t xregsize;
 791                         int abisize;
 792 
 793                         xregsize = prgetprxregsize(p);
 794                         prunlock(pnp);
 795                         if (xregsize > INT_MAX) {
 796                                 error = EOVERFLOW;
 797                                 break;
 798                         }
 799 
 800                         abisize = (int)xregsize;
 801                         if (copyout(&abisize, cmaddr, sizeof (abisize)))
 802                                 error = EFAULT;
 803                 } else {
 804                         prunlock(pnp);
 805                         error = EINVAL; /* No extra register support */
 806                 }
 807                 break;
 808         }
 809 
 810         case PIOCGXREG:         /* get extra registers */
 811                 if (prhasx(p)) {
 812                         bzero(thing, thingsize);
 813                         if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
 814                                 /* drop p_lock to touch the stack */
 815                                 mutex_exit(&p->p_lock);
 816                                 prgetprxregs(lwp, thing);
 817                                 mutex_enter(&p->p_lock);
 818                         }
 819                         prunlock(pnp);
 820                         if (copyout(thing, cmaddr, thingsize))
 821                                 error = EFAULT;
 822                 } else {
 823                         prunlock(pnp);
 824                         error = EINVAL; /* No extra register support */
 825                 }
 826                 if (thing) {
 827                         kmem_free(thing, thingsize);
 828                         thing = NULL;
 829                 }
 830                 break;
 831 
 832         case PIOCSTATUS:        /* get process/lwp status */
 833                 oprgetstatus(t, &un.prstat, VTOZONE(vp));
 834                 prunlock(pnp);
 835                 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
 836                         error = EFAULT;
 837                 break;
 838 
 839         case PIOCLSTATUS:       /* get status for process & all lwps */
 840         {
 841                 int Nlwp;
 842                 int nlwp;
 843                 prstatus_t *Bprsp;
 844                 prstatus_t *prsp;
 845 
 846                 nlwp = Nlwp = p->p_lwpcnt;
 847 
 848                 if (thing && thingsize != (Nlwp+1) * sizeof (prstatus_t)) {
 849                         kmem_free(thing, thingsize);
 850                         thing = NULL;
 851                 }
 
1733          * Support for old /proc interface.
1734          */
1735         if (pnp->pr_pidfile != NULL) {
1736                 ASSERT(pnp->pr_type == PR_PIDDIR);
1737                 vp = pnp->pr_pidfile;
1738                 pnp = VTOP(vp);
1739                 ASSERT(pnp->pr_type == PR_PIDFILE);
1740         }
1741 
1742         if (pnp->pr_type != PR_PIDFILE && pnp->pr_type != PR_LWPIDFILE)
1743                 return (ENOTTY);
1744 
1745         /*
1746          * Fail ioctls which are logically "write" requests unless
1747          * the user has write permission.
1748          */
1749         if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
1750                 return (EBADF);
1751 
1752         /*
1753          * The following commands are no longer supported. They were present on
1754          * SPARC and were always errors on other platforms. We now explicitly
1755          * return ENOTSUP to indicate that this is no longer done.
1756          */
1757         switch (cmd) {
1758         case PIOCSXREG:
1759                 return (ENOTSUP);
1760         default:
1761                 break;
1762         }
1763 
1764         /*
1765          * Perform any necessary copyin() operations before
1766          * locking the process.  Helps avoid deadlocks and
1767          * improves performance.
1768          *
1769          * Also, detect invalid ioctl codes here to avoid
1770          * locking a process unnecessarily.
1771          *
1772          * Also, prepare to allocate space that will be needed below,
1773          * case by case.
1774          */
1775         error = 0;
1776         switch (cmd) {
1777         case PIOCGETPR:
1778                 thingsize = sizeof (proc_t);
1779                 break;
1780         case PIOCGETU:
1781                 thingsize = sizeof (user_t);
1782                 break;
1783         case PIOCSTOP:
1784         case PIOCWSTOP:
1785         case PIOCLWPIDS:
1786         case PIOCGTRACE:
1787         case PIOCGENTRY:
1788         case PIOCGEXIT:
1789         case PIOCSRLC:
1790         case PIOCRRLC:
1791         case PIOCSFORK:
1792         case PIOCRFORK:
1793         case PIOCGREG:
1794         case PIOCGFPREG:
1795         case PIOCSTATUS:
1796         case PIOCLSTATUS:
1797         case PIOCPSINFO:
1798         case PIOCMAXSIG:
1799         case PIOCGXREGSIZE:
1800                 break;
1801         case PIOCGXREG:         /* get extra registers */
1802                 thingsize = prgetprxregsize(p);
1803                 break;
1804         case PIOCACTION:
1805                 thingsize = (nsig-1) * sizeof (struct sigaction32);
1806                 break;
1807         case PIOCGHOLD:
1808         case PIOCNMAP:
1809         case PIOCMAP:
1810         case PIOCGFAULT:
1811         case PIOCCFAULT:
1812         case PIOCCRED:
1813         case PIOCGROUPS:
1814         case PIOCUSAGE:
1815         case PIOCLUSAGE:
1816                 break;
1817         case PIOCOPENPD:
1818                 /*
1819                  * We will need this below.
1820                  * Allocate it now, before locking the process.
1821                  */
1822                 xpnp = prgetnode(vp, PR_OPAGEDATA);
 
1923         /*
1924          * If we need kmem_alloc()d space then we allocate it now, before
1925          * grabbing the process lock.  Using kmem_alloc(KM_SLEEP) while
1926          * holding the process lock leads to deadlock with the clock thread.
1927          * (The clock thread wakes up the pageout daemon to free up space.
1928          * If the clock thread blocks behind us and we are sleeping waiting
1929          * for space, then space may never become available.)
1930          */
1931         if (thingsize) {
1932                 ASSERT(thing == NULL);
1933                 thing = kmem_alloc(thingsize, KM_SLEEP);
1934         }
1935 
1936         switch (cmd) {
1937         case PIOCPSINFO:
1938         case PIOCGETPR:
1939         case PIOCUSAGE:
1940         case PIOCLUSAGE:
1941                 zdisp = ZYES;
1942                 break;
1943         default:
1944                 zdisp = ZNO;
1945                 break;
1946         }
1947 
1948         if ((error = prlock(pnp, zdisp)) != 0) {
1949                 if (thing != NULL)
1950                         kmem_free(thing, thingsize);
1951                 if (xpnp)
1952                         prfreenode(xpnp);
1953                 return (error);
1954         }
1955 
1956         pcp = pnp->pr_common;
1957         p = pcp->prc_proc;
1958         ASSERT(p != NULL);
1959 
1960         /*
1961          * Choose a thread/lwp for the operation.
1962          */
 
2349                 break;
2350 
2351         case PIOCSFPREG:        /* set floating-point registers */
2352                 if (!prhasfp())
2353                         error = EINVAL; /* No FP support */
2354                 else if (PROCESS_NOT_32BIT(p))
2355                         error = EOVERFLOW;
2356                 else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
2357                         error = EBUSY;
2358                 else {
2359                         /* drop p_lock while touching the lwp's stack */
2360                         mutex_exit(&p->p_lock);
2361                         prsetprfpregs32(lwp, &un32.fpregs);
2362                         mutex_enter(&p->p_lock);
2363                 }
2364                 prunlock(pnp);
2365                 break;
2366 
2367         case PIOCGXREGSIZE:     /* get the size of the extra registers */
2368         {
2369                 if (prhasx(p)) {
2370                         size_t xregsize;
2371                         int abisize;
2372 
2373                         xregsize = prgetprxregsize(p);
2374                         prunlock(pnp);
2375                         if (xregsize > INT_MAX) {
2376                                 error = EOVERFLOW;
2377                                 break;
2378                         }
2379 
2380                         abisize = (int)xregsize;
2381                         if (copyout(&abisize, cmaddr, sizeof (abisize)))
2382                                 error = EFAULT;
2383                 } else {
2384                         prunlock(pnp);
2385                         error = EINVAL; /* No extra register support */
2386                 }
2387                 break;
2388         }
2389 
2390         case PIOCGXREG:         /* get extra registers */
2391                 if (PROCESS_NOT_32BIT(p))
2392                         error = EOVERFLOW;
2393                 else if (!prhasx(p))
2394                         error = EINVAL; /* No extra register support */
2395                 else {
2396                         bzero(thing, thingsize);
2397                         if (t->t_state == TS_STOPPED || VSTOPPED(t)) {
2398                                 /* drop p_lock to touch the stack */
2399                                 mutex_exit(&p->p_lock);
2400                                 prgetprxregs(lwp, thing);
2401                                 mutex_enter(&p->p_lock);
2402                         }
2403                 }
2404                 prunlock(pnp);
2405                 if (error == 0 &&
2406                     copyout(thing, cmaddr, thingsize))
2407                         error = EFAULT;
2408                 if (thing) {
2409                         kmem_free(thing, thingsize);
2410                         thing = NULL;
2411                 }
2412                 break;
2413 
2414         case PIOCSTATUS:        /* get process/lwp status */
2415                 if (PROCESS_NOT_32BIT(p)) {
2416                         prunlock(pnp);
2417                         error = EOVERFLOW;
2418                         break;
2419                 }
2420                 oprgetstatus32(t, &un32.prstat, VTOZONE(vp));
2421                 prunlock(pnp);
2422                 if (copyout(&un32.prstat, cmaddr, sizeof (un32.prstat)))
2423                         error = EFAULT;
2424                 break;
2425 
2426         case PIOCLSTATUS:       /* get status for process & all lwps */
2427         {
2428                 int Nlwp;
2429                 int nlwp;
 
 |