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,30 ****
--- 21,31 ----
  
  /*
   * 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,222 ****
           */
          if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
                  return (EBADF);
  
          /*
           * 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.
           *
           * Also, prepare to allocate space that will be needed below,
           * case by case.
           */
          error = 0;
--- 208,235 ----
           */
          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 unnecessarily.
           *
           * Also, prepare to allocate space that will be needed below,
           * case by case.
           */
          error = 0;
*** 243,259 ****
          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
                  break;
          case PIOCACTION:
                  thingsize = (nsig-1) * sizeof (struct sigaction);
                  break;
          case PIOCGHOLD:
--- 256,267 ----
          case PIOCLSTATUS:
          case PIOCPSINFO:
          case PIOCMAXSIG:
          case PIOCGXREGSIZE:
                  break;
          case PIOCGXREG:         /* get extra registers */
!                 thingsize = prgetprxregsize(p);
                  break;
          case PIOCACTION:
                  thingsize = (nsig-1) * sizeof (struct sigaction);
                  break;
          case PIOCGHOLD:
*** 390,410 ****
          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;
          }
  
--- 398,407 ----
*** 787,802 ****
                  prunlock(pnp);
                  break;
  
          case PIOCGXREGSIZE:     /* get the size of the extra registers */
          {
-                 int xregsize;
- 
                  if (prhasx(p)) {
                          xregsize = prgetprxregsize(p);
                          prunlock(pnp);
!                         if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
                                  error = EFAULT;
                  } else {
                          prunlock(pnp);
                          error = EINVAL; /* No extra register support */
                  }
--- 784,806 ----
                  prunlock(pnp);
                  break;
  
          case PIOCGXREGSIZE:     /* get the size of the extra registers */
          {
                  if (prhasx(p)) {
+                         size_t xregsize;
+                         int abisize;
+ 
                          xregsize = prgetprxregsize(p);
                          prunlock(pnp);
!                         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,850 ****
                          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;
--- 827,836 ----
*** 1762,1777 ****
           */
          if ((flag & FWRITE) == 0 && isprwrioctl(cmd))
                  return (EBADF);
  
          /*
           * 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.
           *
           * Also, prepare to allocate space that will be needed below,
           * case by case.
           */
          error = 0;
--- 1748,1775 ----
           */
          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 unnecessarily.
           *
           * Also, prepare to allocate space that will be needed below,
           * case by case.
           */
          error = 0;
*** 1798,1814 ****
          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
                  break;
          case PIOCACTION:
                  thingsize = (nsig-1) * sizeof (struct sigaction32);
                  break;
          case PIOCGHOLD:
--- 1796,1807 ----
          case PIOCLSTATUS:
          case PIOCPSINFO:
          case PIOCMAXSIG:
          case PIOCGXREGSIZE:
                  break;
          case PIOCGXREG:         /* get extra registers */
!                 thingsize = prgetprxregsize(p);
                  break;
          case PIOCACTION:
                  thingsize = (nsig-1) * sizeof (struct sigaction32);
                  break;
          case PIOCGHOLD:
*** 1945,1965 ****
          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;
          }
  
--- 1938,1947 ----
*** 2382,2397 ****
                  prunlock(pnp);
                  break;
  
          case PIOCGXREGSIZE:     /* get the size of the extra registers */
          {
-                 int xregsize;
- 
                  if (prhasx(p)) {
                          xregsize = prgetprxregsize(p);
                          prunlock(pnp);
!                         if (copyout(&xregsize, cmaddr, sizeof (xregsize)))
                                  error = EFAULT;
                  } else {
                          prunlock(pnp);
                          error = EINVAL; /* No extra register support */
                  }
--- 2364,2386 ----
                  prunlock(pnp);
                  break;
  
          case PIOCGXREGSIZE:     /* get the size of the extra registers */
          {
                  if (prhasx(p)) {
+                         size_t xregsize;
+                         int abisize;
+ 
                          xregsize = prgetprxregsize(p);
                          prunlock(pnp);
!                         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,2445 ****
                  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 */
--- 2405,2414 ----