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
        
*** 22,31 ****
--- 22,35 ----
  /*
   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
+ /*
+  * Copyright 2023 Oxide Computer Company
+  */
+ 
          .file   "getcontext.s"
  
  #include <sys/asm_linkage.h>
  
          ANSI_PRAGMA_WEAK(getcontext,function)
*** 42,55 ****
   * As swapcontext() is actually equivalent to getcontext() + setcontext(),
   * swapcontext() shares the most code with getcontext().
   */
  
  
! #define GETCONTEXT_IMPL                                                 \
          movl    4(%esp), %eax;          /* %eax <-- first arg: ucp */   \
          pushl   %eax;                   /* push ucp for system call */  \
!         call    __getcontext;           /* call getcontext: syscall */  \
          addl    $4, %esp;               /* pop arg */                   \
          andl    %eax, %eax;             /* if (err_ret_from_syscall) */ \
          je      1f;                                                     \
          ret;                            /*      then return */          \
  1:                                                                      \
--- 46,59 ----
   * As swapcontext() is actually equivalent to getcontext() + setcontext(),
   * swapcontext() shares the most code with getcontext().
   */
  
  
! #define GETCONTEXT_IMPL(func)                                           \
          movl    4(%esp), %eax;          /* %eax <-- first arg: ucp */   \
          pushl   %eax;                   /* push ucp for system call */  \
!         call    func;                   /* call getcontext: syscall */  \
          addl    $4, %esp;               /* pop arg */                   \
          andl    %eax, %eax;             /* if (err_ret_from_syscall) */ \
          je      1f;                                                     \
          ret;                            /*      then return */          \
  1:                                                                      \
*** 68,92 ****
          xorl    %eax, %eax;     /* return 0 */                          \
          movl    %eax, EAX_OFF (%edx);                                   \
                                  /* getcontext returns 0 after a setcontext */
  
  /*
!  * getcontext(ucontext_t *ucp)
   */
          ENTRY(getcontext)
!         GETCONTEXT_IMPL
          ret
          SET_SIZE(getcontext)
  
  
  /*
!  * swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
   */
          ENTRY(swapcontext)
!         GETCONTEXT_IMPL
!         / call setcontext
          movl    8(%esp), %eax           /* %eax <-- second arg: ucp */
          pushl   %eax                    /* push ucp for setcontext */
          call    setcontext
          addl    $4, %esp                /* pop arg: just in case */
          ret
          SET_SIZE(swapcontext)
--- 72,130 ----
          xorl    %eax, %eax;     /* return 0 */                          \
          movl    %eax, EAX_OFF (%edx);                                   \
                                  /* getcontext returns 0 after a setcontext */
  
  /*
!  * int getcontext(ucontext_t *ucp)
   */
          ENTRY(getcontext)
!         GETCONTEXT_IMPL(__getcontext)
          ret
          SET_SIZE(getcontext)
  
  
  /*
!  * int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
   */
          ENTRY(swapcontext)
!         GETCONTEXT_IMPL(__getcontext)
!         /* call setcontext */
          movl    8(%esp), %eax           /* %eax <-- second arg: ucp */
          pushl   %eax                    /* push ucp for setcontext */
          call    setcontext
          addl    $4, %esp                /* pop arg: just in case */
          ret
          SET_SIZE(swapcontext)
+ 
+ /*
+  * int getcontext_extd(ucontext_t *ucp, uint32_t flags)
+  */
+         ENTRY(getcontext_extd)
+         movl    8(%esp), %eax
+         cmpl    $0, %eax                /* if (flags != 0) */
+         jne     2f
+         GETCONTEXT_IMPL(__getcontext_extd)
+         ret
+ 2:
+         movl    $EINVAL, %eax           /* errno = EINVAL; */
+         jmp     __cerror                /* return (-1) */
+         SET_SIZE(getcontext_extd)
+ 
+ 
+ /*
+  * int swapcontext_extd(ucontext_t *oucp, const ucontext_t *ucp)
+  */
+         ENTRY(swapcontext_extd)
+         movl    8(%esp), %eax
+         cmpl    $0, %eax                /* if (flags != 0) */
+         jne     2f
+         GETCONTEXT_IMPL(__getcontext_extd)
+         /* call setcontext */
+         movl    12(%esp), %eax          /* %eax <-- second arg: ucp */
+         pushl   %eax                    /* push ucp for setcontext */
+         call    setcontext
+         addl    $4, %esp                /* pop arg: just in case */
+         ret
+ 2:
+         movl    $EINVAL, %eax           /* errno = EINVAL; */
+         jmp     __cerror                /* return (-1) */
+         SET_SIZE(swapcontext_extd)