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,10 +22,14 @@
 /*
  * 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,14 +46,14 @@
  * As swapcontext() is actually equivalent to getcontext() + setcontext(),
  * swapcontext() shares the most code with getcontext().
  */
 
 
-#define GETCONTEXT_IMPL                                                 \
+#define GETCONTEXT_IMPL(func)                                           \
         movl    4(%esp), %eax;          /* %eax <-- first arg: ucp */   \
         pushl   %eax;                   /* push ucp for system call */  \
-        call    __getcontext;           /* call getcontext: syscall */  \
+        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,25 +72,59 @@
         xorl    %eax, %eax;     /* return 0 */                          \
         movl    %eax, EAX_OFF (%edx);                                   \
                                 /* getcontext returns 0 after a setcontext */
 
 /*
- * getcontext(ucontext_t *ucp)
+ * int getcontext(ucontext_t *ucp)
  */
         ENTRY(getcontext)
-        GETCONTEXT_IMPL
+        GETCONTEXT_IMPL(__getcontext)
         ret
         SET_SIZE(getcontext)
 
 
 /*
- * swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
+ * int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
  */
         ENTRY(swapcontext)
-        GETCONTEXT_IMPL
-        / call setcontext
+        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)