Print this page
15254 %ymm registers not restored after signal handler
15367 x86 getfpregs() summons corrupting %xmm ghosts
15333 want x86 /proc xregs support (libc_db, libproc, mdb, etc.)
15336 want libc functions for extended ucontext_t
15334 want ps_lwphandle-specific reg routines
15328 FPU_CW_INIT mistreats reserved bit
15335 i86pc fpu_subr.c isn't really platform-specific
15332 setcontext(2) isn't actually noreturn
15331 need <sys/stdalign.h>
Change-Id: I7060aa86042dfb989f77fc3323c065ea2eafa9ad
Conflicts:
    usr/src/uts/common/fs/proc/prcontrol.c
    usr/src/uts/intel/os/archdep.c
    usr/src/uts/intel/sys/ucontext.h
    usr/src/uts/intel/syscall/getcontext.c
        
@@ -21,10 +21,11 @@
 
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright 2019 Joyent, Inc.
+ * Copyright 2023 Oxide Computer Company
  */
 
 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
 /*        All rights reserved.  */
 
@@ -207,16 +208,28 @@
          */
         if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
                 return (EBADF);
 
         /*
+         * The following commands are no longer supported. They were present on
+         * SPARC and were always errors on other platforms. We now explicitly
+         * return ENOTSUP to indicate that this is no longer done.
+         */
+        switch (cmd) {
+        case PIOCSXREG:
+                return (ENOTSUP);
+        default:
+                break;
+        }
+
+        /*
          * Perform any necessary copyin() operations before
          * locking the process.  Helps avoid deadlocks and
          * improves performance.
          *
          * Also, detect invalid ioctl codes here to avoid
-         * locking a process unnnecessarily.
+         * locking a process unnecessarily.
          *
          * Also, prepare to allocate space that will be needed below,
          * case by case.
          */
         error = 0;
@@ -243,17 +256,12 @@
         case PIOCLSTATUS:
         case PIOCPSINFO:
         case PIOCMAXSIG:
         case PIOCGXREGSIZE:
                 break;
-        case PIOCSXREG:         /* set extra registers */
         case PIOCGXREG:         /* get extra registers */
-#if defined(__sparc)
-                thingsize = sizeof (prxregset_t);
-#else
-                thingsize = 0;
-#endif
+                thingsize = prgetprxregsize(p);
                 break;
         case PIOCACTION:
                 thingsize = (nsig-1) * sizeof (struct sigaction);
                 break;
         case PIOCGHOLD:
@@ -390,21 +398,10 @@
         case PIOCGETPR:
         case PIOCUSAGE:
         case PIOCLUSAGE:
                 zdisp = ZYES;
                 break;
-        case PIOCSXREG:         /* set extra registers */
-                /*
-                 * perform copyin before grabbing the process lock
-                 */
-                if (thing) {
-                        if (copyin(cmaddr, thing, thingsize)) {
-                                kmem_free(thing, thingsize);
-                                return (EFAULT);
-                        }
-                }
-                /* fall through... */
         default:
                 zdisp = ZNO;
                 break;
         }
 
@@ -787,16 +784,23 @@
                 prunlock(pnp);
                 break;
 
         case PIOCGXREGSIZE:     /* get the size of the extra registers */
         {
-                int xregsize;
-
                 if (prhasx(p)) {
+                        size_t xregsize;
+                        int abisize;
+
                         xregsize = prgetprxregsize(p);
                         prunlock(pnp);
-                        if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
+                        if (xregsize > INT_MAX) {
+                                error = EOVERFLOW;
+                                break;
+                        }
+
+                        abisize = (int)xregsize;
+                        if (copyout(&abisize, cmaddr, sizeof (abisize)))
                                 error = EFAULT;
                 } else {
                         prunlock(pnp);
                         error = EINVAL; /* No extra register support */
                 }
@@ -823,28 +827,10 @@
                         kmem_free(thing, thingsize);
                         thing = NULL;
                 }
                 break;
 
-        case PIOCSXREG:         /* set extra registers */
-                if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
-                        error = EBUSY;
-                else if (!prhasx(p))
-                        error = EINVAL; /* No extra register support */
-                else if (thing) {
-                        /* drop p_lock while touching the lwp's stack */
-                        mutex_exit(&p->p_lock);
-                        prsetprxregs(lwp, thing);
-                        mutex_enter(&p->p_lock);
-                }
-                prunlock(pnp);
-                if (thing) {
-                        kmem_free(thing, thingsize);
-                        thing = NULL;
-                }
-                break;
-
         case PIOCSTATUS:        /* get process/lwp status */
                 oprgetstatus(t, &un.prstat, VTOZONE(vp));
                 prunlock(pnp);
                 if (copyout(&un.prstat, cmaddr, sizeof (un.prstat)))
                         error = EFAULT;
@@ -1762,16 +1748,28 @@
          */
         if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
                 return (EBADF);
 
         /*
+         * The following commands are no longer supported. They were present on
+         * SPARC and were always errors on other platforms. We now explicitly
+         * return ENOTSUP to indicate that this is no longer done.
+         */
+        switch (cmd) {
+        case PIOCSXREG:
+                return (ENOTSUP);
+        default:
+                break;
+        }
+
+        /*
          * Perform any necessary copyin() operations before
          * locking the process.  Helps avoid deadlocks and
          * improves performance.
          *
          * Also, detect invalid ioctl codes here to avoid
-         * locking a process unnnecessarily.
+         * locking a process unnecessarily.
          *
          * Also, prepare to allocate space that will be needed below,
          * case by case.
          */
         error = 0;
@@ -1798,17 +1796,12 @@
         case PIOCLSTATUS:
         case PIOCPSINFO:
         case PIOCMAXSIG:
         case PIOCGXREGSIZE:
                 break;
-        case PIOCSXREG:         /* set extra registers */
         case PIOCGXREG:         /* get extra registers */
-#if defined(__sparc)
-                thingsize = sizeof (prxregset_t);
-#else
-                thingsize = 0;
-#endif
+                thingsize = prgetprxregsize(p);
                 break;
         case PIOCACTION:
                 thingsize = (nsig-1) * sizeof (struct sigaction32);
                 break;
         case PIOCGHOLD:
@@ -1945,21 +1938,10 @@
         case PIOCGETPR:
         case PIOCUSAGE:
         case PIOCLUSAGE:
                 zdisp = ZYES;
                 break;
-        case PIOCSXREG:         /* set extra registers */
-                /*
-                 * perform copyin before grabbing the process lock
-                 */
-                if (thing) {
-                        if (copyin(cmaddr, thing, thingsize)) {
-                                kmem_free(thing, thingsize);
-                                return (EFAULT);
-                        }
-                }
-                /* fall through... */
         default:
                 zdisp = ZNO;
                 break;
         }
 
@@ -2382,16 +2364,23 @@
                 prunlock(pnp);
                 break;
 
         case PIOCGXREGSIZE:     /* get the size of the extra registers */
         {
-                int xregsize;
-
                 if (prhasx(p)) {
+                        size_t xregsize;
+                        int abisize;
+
                         xregsize = prgetprxregsize(p);
                         prunlock(pnp);
-                        if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
+                        if (xregsize > INT_MAX) {
+                                error = EOVERFLOW;
+                                break;
+                        }
+
+                        abisize = (int)xregsize;
+                        if (copyout(&abisize, cmaddr, sizeof (abisize)))
                                 error = EFAULT;
                 } else {
                         prunlock(pnp);
                         error = EINVAL; /* No extra register support */
                 }
@@ -2416,30 +2405,10 @@
                 if (error == 0 &&
                     copyout(thing, cmaddr, thingsize))
                         error = EFAULT;
                 if (thing) {
                         kmem_free(thing, thingsize);
-                        thing = NULL;
-                }
-                break;
-
-        case PIOCSXREG:         /* set extra registers */
-                if (PROCESS_NOT_32BIT(p))
-                        error = EOVERFLOW;
-                else if (!ISTOPPED(t) && !VSTOPPED(t) && !DSTOPPED(t))
-                        error = EBUSY;
-                else if (!prhasx(p))
-                        error = EINVAL; /* No extra register support */
-                else if (thing) {
-                        /* drop p_lock while touching the lwp's stack */
-                        mutex_exit(&p->p_lock);
-                        prsetprxregs(lwp, thing);
-                        mutex_enter(&p->p_lock);
-                }
-                prunlock(pnp);
-                if (thing) {
-                        kmem_free(thing, thingsize);
                         thing = NULL;
                 }
                 break;
 
         case PIOCSTATUS:        /* get process/lwp status */