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

@@ -19,11 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2018, Joyent, Inc.
- * Copyright 2022 Oxide Computer Company
+ * Copyright 2023 Oxide Computer Company
  *
  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */

@@ -133,14 +133,25 @@
  * Initial value of FPU control word as per 4th ed. ABI document
  * - affine infinity
  * - round to nearest or even
  * - 64-bit double precision
  * - all exceptions masked
+ *
+ * The 4th ed. SVR4 ABI didn't discuss the value of reserved bits. The ISA
+ * defines bit 6 (0x40) as reserved, but also that it is set (rather than clear,
+ * like many other Reserved bits). We preserve that in our value here.
  */
-#define FPU_CW_INIT     0x133f
+#define FPU_CW_INIT     0x137f
 
 /*
+ * This is the Intel mandated form of the default value of the x87 control word.
+ * This is different from what we use and should only be used in the context of
+ * representing that default state (e.g. in /proc xregs).
+ */
+#define FPU_CW_INIT_HW  0x037f
+
+/*
  * masks and flags for SSE/SSE2 MXCSR
  */
 #define SSE_IE  0x00000001      /* invalid operation                    */
 #define SSE_DE  0x00000002      /* denormalized operand                 */
 #define SSE_ZE  0x00000004      /* zero divide                          */

@@ -299,22 +310,21 @@
  */
 typedef struct {
         union _kfpu_u {
                 void *kfpu_generic;
                 struct fxsave_state *kfpu_fx;
-#if defined(__i386)
-                struct fnsave_state *kfpu_fn;
-#endif
                 struct xsave_state *kfpu_xs;
         } kfpu_u;
         uint32_t kfpu_status;           /* saved at #mf exception */
         uint32_t kfpu_xstatus;          /* saved at #xm exception */
 } kfpu_t;
 
 extern int fp_kind;             /* kind of fp support                   */
 extern int fp_save_mech;        /* fp save/restore mechanism            */
 extern int fpu_exists;          /* FPU hw exists                        */
+extern int fp_elf;              /* FP elf type */
+extern uint64_t xsave_bv_all;   /* Set of enabed xcr0 values */
 
 #ifdef _KERNEL
 
 extern int fpu_ignored;
 extern int fpu_pentium_fdivbug;

@@ -323,10 +333,11 @@
 
 extern void fpu_probe(void);
 extern uint_t fpu_initial_probe(void);
 
 extern void fpu_auxv_info(int *, size_t *);
+extern boolean_t fpu_xsave_enabled(void);
 
 extern void fpnsave_ctxt(void *);
 extern void fpxsave_ctxt(void *);
 extern void xsave_ctxt(void *);
 extern void xsaveopt_ctxt(void *);

@@ -339,12 +350,10 @@
 extern void fpxrestore_ctxt(void *);
 extern void xrestore_ctxt(void *);
 extern void (*fprestore_ctxt)(void *);
 
 extern void fxsave_insn(struct fxsave_state *);
-extern void fpsave(struct fnsave_state *);
-extern void fprestore(struct fnsave_state *);
 extern void fpxsave(struct fxsave_state *);
 extern void fpxrestore(struct fxsave_state *);
 extern void xsave(struct xsave_state *, uint64_t);
 extern void xsaveopt(struct xsave_state *, uint64_t);
 extern void xrestore(struct xsave_state *, uint64_t);

@@ -371,10 +380,26 @@
 extern void fp_lwp_dup(struct _klwp *);
 
 extern const struct fxsave_state sse_initial;
 extern const struct xsave_state avx_initial;
 
+struct proc;
+struct ucontext;
+extern void fpu_proc_xregs_info(struct proc *, uint32_t *, uint32_t *,
+    uint32_t *);
+extern size_t fpu_proc_xregs_max_size(void);
+extern void fpu_proc_xregs_get(struct _klwp *, void *);
+extern int fpu_proc_xregs_set(struct _klwp *, void *);
+extern int fpu_signal_copyin(struct _klwp *, struct ucontext *);
+typedef int (*fpu_copyout_f)(const void *, void *, size_t);
+extern int fpu_signal_copyout(struct _klwp *, uintptr_t, fpu_copyout_f);
+extern void fpu_set_xsave(struct _klwp *, const void *);
+extern size_t fpu_signal_size(struct _klwp *);
+
+extern void fpu_get_fpregset(struct _klwp *, fpregset_t *);
+extern void fpu_set_fpregset(struct _klwp *, const fpregset_t *);
+
 #endif  /* _KERNEL */
 
 #ifdef __cplusplus
 }
 #endif