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)

@@ -40,13 +44,13 @@
  *
  * As swapcontext() is actually equivalent to getcontext() + setcontext(),
  * swapcontext() shares the most code with getcontext().
  */
 
-#define GETCONTEXT_IMPL(offset)                                         \
+#define GETCONTEXT_IMPL(offset, func)                                           \
         pushq   %rdi;           /* preserve the ucontext_t pointer */   \
-        call    __getcontext;                                           \
+        call    func;                                           \
                                 /* call getcontext: syscall */          \
         popq    %rdx;                                                   \
         andl    %eax, %eax;     /* if (error_return_from_syscall) */    \
         je      1f;                                                     \
         addq    $offset, %rsp;                                          \

@@ -68,27 +72,60 @@
         xorq    %rax, %rax;     /* return 0 */                          \
         movq    %rax, RAX_OFF (%rdx);                                   \
                                 /* getcontext returns 0 after setcontext */
 
 /*      
- * getcontext(ucontext_t *ucp)
+ * int getcontext(ucontext_t *ucp)
  */
 
         ENTRY(getcontext)
-        GETCONTEXT_IMPL(0)
+        GETCONTEXT_IMPL(0, __getcontext)
         ret
         SET_SIZE(getcontext)
 
 /*
- * swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
+ * int swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
  */
 
         ENTRY(swapcontext)
         pushq   %rsi                    /* preserve the 2nd argument */
         
-        GETCONTEXT_IMPL(8)
+        GETCONTEXT_IMPL(8, __getcontext)
 
         /* call setcontext */
         popq    %rdi
         call    setcontext
         ret
         SET_SIZE(swapcontext)
+
+/*
+ * int getcontext_extd(ucontext_t * ctx, uint32_t flags)
+ */
+        ENTRY(getcontext_extd)
+        cmpl    $0, %esi
+        jne     2f
+        GETCONTEXT_IMPL(0, __getcontext_extd)
+        ret
+2:
+        movl    $EINVAL, %eax           /* errno = EINVAL */
+        jmp     __cerror                /* return (-1) */
+        SET_SIZE(getcontext_extd)
+
+/*
+ * int swapcontext_extd(ucontext_t *oucp, uint32_t flags, const ucontext_t *ucp)
+ */
+
+        ENTRY(swapcontext_extd)
+        cmpl    $0, %esi
+        jne     2f
+        pushq   %rdx                    /* preserve the 3rd argument */
+
+        GETCONTEXT_IMPL(8, __getcontext_extd)
+
+        /* call setcontext */
+        popq    %rdi
+        call    setcontext
+        ret
+2:
+        movl    $EINVAL, %eax           /* errno = EINVAL */
+        jmp     __cerror                /* return (-1) */
+        SET_SIZE(swapcontext_extd)