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
        
*** 25,40 ****
--- 25,47 ----
   */
  
  /*      Copyright (c) 1988 AT&T */
  /*        All Rights Reserved   */
  
+ /*
+  * Copyright 2023 Oxide Computer Company
+  */
+ 
  #pragma weak _makecontext = makecontext
  
  #include "lint.h"
  #include <stdarg.h>
  #include <ucontext.h>
  #include <sys/stack.h>
+ #include <sys/auxv.h>
+ #include <errno.h>
+ #include "libc.h"
  
  /*
   * The ucontext_t that the user passes in must have been primed with a
   * call to getcontext(2), have the uc_stack member set to reflect the
   * stack which this context will use, and have the uc_link member set
*** 113,118 ****
--- 120,184 ----
  {
          ucontext_t uc;
  
          (void) getcontext(&uc);
          (void) setcontext(uc.uc_link);
+ }
+ 
+ /*
+  * This is the ISA-specific allocation logic for allocating and setting up an
+  * extended ucontext_t. In particular, right now we need to allocate and add
+  * space for the UC_XSAVE member if we have the appropriate hardware support.
+  * The i386 / amd64 versions could be consolidated in a single x86 impl, but we
+  * don't have that right now.
+  */
+ ucontext_t *
+ ucontext_alloc(uint32_t flags)
+ {
+         boolean_t do_xsave = B_FALSE;
+         size_t to_alloc = sizeof (ucontext_t);
+         ucontext_t *ucp;
+ 
+         if (flags != 0) {
+                 errno = EINVAL;
+                 return (NULL);
+         }
+ 
+         /*
+          * This value isn't really 100% accurate. The xsave size is basically
+          * the worst case that we can have. The XMM / xsave structures aren't
+          * included in here, but are going to be enough to cover this. We can
+          * probably try to do a little better and should consider asking the
+          * kernel for something more accurate. In particular, the problem with
+          * tis is that it doesn't account for the right size of future-looking
+          * dynamic things, but then again neither does rtld. We'll deal with
+          * this when we have support for the xfd MSR and actually use it. For
+          * more information see uts/intel/os/fpu.c's big theory statement.
+          */
+         switch (___getauxval(AT_SUN_FPTYPE)) {
+         case AT_386_FPINFO_XSAVE:
+         case AT_386_FPINFO_XSAVE_AMD:
+                 do_xsave = B_TRUE;
+                 to_alloc += ___getauxval(AT_SUN_FPSIZE);
+                 break;
+         default:
+                 break;
+         }
+ 
+         ucp = calloc(1, to_alloc);
+         if (ucp == NULL) {
+                 return (NULL);
+         }
+ 
+         if (do_xsave) {
+                 uintptr_t addr = (uintptr_t)ucp;
+                 ucp->uc_xsave = addr + sizeof (ucontext_t);
+         }
+ 
+         return (ucp);
+ }
+ 
+ void
+ ucontext_free(ucontext_t *ucp)
+ {
+         free(ucp);
  }