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


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  23  * Copyright (c) 2018, Joyent, Inc.
  24  * Copyright 2022 Oxide Computer Company
  25  *
  26  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  27  */
  28 
  29 /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
  30 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T       */
  31 /*              All Rights Reserved                             */
  32 
  33 #ifndef _SYS_FP_H
  34 #define _SYS_FP_H
  35 
  36 #ifdef __cplusplus
  37 extern "C" {
  38 #endif
  39 
  40 /*
  41  * 80287/80387 and SSE/SSE2 floating point processor definitions
  42  */
  43 
  44 /*


 118 #define FPS_ES  0x00000080      /* error summary bit                    */
 119 #define FPS_C0  0x00000100      /* C0 bit                               */
 120 #define FPS_C1  0x00000200      /* C1 bit                               */
 121 #define FPS_C2  0x00000400      /* C2 bit                               */
 122 #define FPS_TOP 0x00003800      /* top of stack pointer                 */
 123 #define FPS_C3  0x00004000      /* C3 bit                               */
 124 #define FPS_B   0x00008000      /* busy bit                             */
 125 
 126 /*
 127  * Exception flags manually cleared during x87 exception handling.
 128  */
 129 #define FPS_SW_EFLAGS   \
 130         (FPS_IE|FPS_DE|FPS_ZE|FPS_OE|FPS_UE|FPS_PE|FPS_SF|FPS_ES|FPS_B)
 131 
 132 /*
 133  * Initial value of FPU control word as per 4th ed. ABI document
 134  * - affine infinity
 135  * - round to nearest or even
 136  * - 64-bit double precision
 137  * - all exceptions masked




 138  */
 139 #define FPU_CW_INIT     0x133f
 140 
 141 /*







 142  * masks and flags for SSE/SSE2 MXCSR
 143  */
 144 #define SSE_IE  0x00000001      /* invalid operation                    */
 145 #define SSE_DE  0x00000002      /* denormalized operand                 */
 146 #define SSE_ZE  0x00000004      /* zero divide                          */
 147 #define SSE_OE  0x00000008      /* overflow                             */
 148 #define SSE_UE  0x00000010      /* underflow                            */
 149 #define SSE_PE  0x00000020      /* precision                            */
 150 #define SSE_DAZ 0x00000040      /* denormals are zero                   */
 151 #define SSE_IM  0x00000080      /* invalid op exception mask            */
 152 #define SSE_DM  0x00000100      /* denormalize exception mask           */
 153 #define SSE_ZM  0x00000200      /* zero-divide exception mask           */
 154 #define SSE_OM  0x00000400      /* overflow exception mask              */
 155 #define SSE_UM  0x00000800      /* underflow exception mask             */
 156 #define SSE_PM  0x00001000      /* precision exception mask             */
 157 #define SSE_RC  0x00006000      /* rounding control                     */
 158 #define SSE_RD  0x00002000      /* rounding control: round down         */
 159 #define SSE_RU  0x00004000      /* rounding control: round up           */
 160 #define SSE_FZ  0x00008000      /* flush to zero for masked underflow   */
 161 


 284         struct xsave_header     xs_header;      /* 512-575 XSAVE header */
 285         upad128_t               xs_ymm[16];     /* 576 AVX component */
 286 } __aligned(64);
 287 
 288 /*
 289  * While AVX_XSTATE_SIZE is the smallest the kernel will allocate for FPU
 290  * state-saving, other consumers may constrain themselves to the minimum
 291  * possible xsave state structure, which features only the legacy area and the
 292  * bare xsave header.
 293  */
 294 #define MIN_XSAVE_SIZE  (sizeof (struct fxsave_state) + \
 295                             sizeof (struct xsave_header))
 296 
 297 /*
 298  * Kernel's FPU save area
 299  */
 300 typedef struct {
 301         union _kfpu_u {
 302                 void *kfpu_generic;
 303                 struct fxsave_state *kfpu_fx;
 304 #if defined(__i386)
 305                 struct fnsave_state *kfpu_fn;
 306 #endif
 307                 struct xsave_state *kfpu_xs;
 308         } kfpu_u;
 309         uint32_t kfpu_status;           /* saved at #mf exception */
 310         uint32_t kfpu_xstatus;          /* saved at #xm exception */
 311 } kfpu_t;
 312 
 313 extern int fp_kind;             /* kind of fp support                   */
 314 extern int fp_save_mech;        /* fp save/restore mechanism            */
 315 extern int fpu_exists;          /* FPU hw exists                        */


 316 
 317 #ifdef _KERNEL
 318 
 319 extern int fpu_ignored;
 320 extern int fpu_pentium_fdivbug;
 321 
 322 extern uint32_t sse_mxcsr_mask;
 323 
 324 extern void fpu_probe(void);
 325 extern uint_t fpu_initial_probe(void);
 326 
 327 extern void fpu_auxv_info(int *, size_t *);

 328 
 329 extern void fpnsave_ctxt(void *);
 330 extern void fpxsave_ctxt(void *);
 331 extern void xsave_ctxt(void *);
 332 extern void xsaveopt_ctxt(void *);
 333 extern void fpxsave_excp_clr_ctxt(void *);
 334 extern void xsave_excp_clr_ctxt(void *);
 335 extern void xsaveopt_excp_clr_ctxt(void *);
 336 extern void (*fpsave_ctxt)(void *);
 337 extern void (*xsavep)(struct xsave_state *, uint64_t);
 338 
 339 extern void fpxrestore_ctxt(void *);
 340 extern void xrestore_ctxt(void *);
 341 extern void (*fprestore_ctxt)(void *);
 342 
 343 extern void fxsave_insn(struct fxsave_state *);
 344 extern void fpsave(struct fnsave_state *);
 345 extern void fprestore(struct fnsave_state *);
 346 extern void fpxsave(struct fxsave_state *);
 347 extern void fpxrestore(struct fxsave_state *);
 348 extern void xsave(struct xsave_state *, uint64_t);
 349 extern void xsaveopt(struct xsave_state *, uint64_t);
 350 extern void xrestore(struct xsave_state *, uint64_t);
 351 
 352 extern void fpenable(void);
 353 extern void fpdisable(void);
 354 extern void fpinit(void);
 355 
 356 extern uint32_t fperr_reset(void);
 357 extern uint32_t fpxerr_reset(void);
 358 
 359 extern uint32_t fpgetcwsw(void);
 360 extern uint32_t fpgetmxcsr(void);
 361 
 362 struct regs;
 363 extern int fpexterrflt(struct regs *);
 364 extern int fpsimderrflt(struct regs *);
 365 extern void fpsetcw(uint16_t, uint32_t);
 366 extern void fp_seed(void);
 367 extern void fp_exec(void);
 368 struct _klwp;
 369 extern void fp_lwp_init(struct _klwp *);
 370 extern void fp_lwp_cleanup(struct _klwp *);
 371 extern void fp_lwp_dup(struct _klwp *);
 372 
 373 extern const struct fxsave_state sse_initial;
 374 extern const struct xsave_state avx_initial;
 375 
















 376 #endif  /* _KERNEL */
 377 
 378 #ifdef __cplusplus
 379 }
 380 #endif
 381 
 382 #endif  /* _SYS_FP_H */


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  23  * Copyright (c) 2018, Joyent, Inc.
  24  * Copyright 2023 Oxide Computer Company
  25  *
  26  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  27  */
  28 
  29 /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
  30 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T       */
  31 /*              All Rights Reserved                             */
  32 
  33 #ifndef _SYS_FP_H
  34 #define _SYS_FP_H
  35 
  36 #ifdef __cplusplus
  37 extern "C" {
  38 #endif
  39 
  40 /*
  41  * 80287/80387 and SSE/SSE2 floating point processor definitions
  42  */
  43 
  44 /*


 118 #define FPS_ES  0x00000080      /* error summary bit                    */
 119 #define FPS_C0  0x00000100      /* C0 bit                               */
 120 #define FPS_C1  0x00000200      /* C1 bit                               */
 121 #define FPS_C2  0x00000400      /* C2 bit                               */
 122 #define FPS_TOP 0x00003800      /* top of stack pointer                 */
 123 #define FPS_C3  0x00004000      /* C3 bit                               */
 124 #define FPS_B   0x00008000      /* busy bit                             */
 125 
 126 /*
 127  * Exception flags manually cleared during x87 exception handling.
 128  */
 129 #define FPS_SW_EFLAGS   \
 130         (FPS_IE|FPS_DE|FPS_ZE|FPS_OE|FPS_UE|FPS_PE|FPS_SF|FPS_ES|FPS_B)
 131 
 132 /*
 133  * Initial value of FPU control word as per 4th ed. ABI document
 134  * - affine infinity
 135  * - round to nearest or even
 136  * - 64-bit double precision
 137  * - all exceptions masked
 138  *
 139  * The 4th ed. SVR4 ABI didn't discuss the value of reserved bits. The ISA
 140  * defines bit 6 (0x40) as reserved, but also that it is set (rather than clear,
 141  * like many other Reserved bits). We preserve that in our value here.
 142  */
 143 #define FPU_CW_INIT     0x137f
 144 
 145 /*
 146  * This is the Intel mandated form of the default value of the x87 control word.
 147  * This is different from what we use and should only be used in the context of
 148  * representing that default state (e.g. in /proc xregs).
 149  */
 150 #define FPU_CW_INIT_HW  0x037f
 151 
 152 /*
 153  * masks and flags for SSE/SSE2 MXCSR
 154  */
 155 #define SSE_IE  0x00000001      /* invalid operation                    */
 156 #define SSE_DE  0x00000002      /* denormalized operand                 */
 157 #define SSE_ZE  0x00000004      /* zero divide                          */
 158 #define SSE_OE  0x00000008      /* overflow                             */
 159 #define SSE_UE  0x00000010      /* underflow                            */
 160 #define SSE_PE  0x00000020      /* precision                            */
 161 #define SSE_DAZ 0x00000040      /* denormals are zero                   */
 162 #define SSE_IM  0x00000080      /* invalid op exception mask            */
 163 #define SSE_DM  0x00000100      /* denormalize exception mask           */
 164 #define SSE_ZM  0x00000200      /* zero-divide exception mask           */
 165 #define SSE_OM  0x00000400      /* overflow exception mask              */
 166 #define SSE_UM  0x00000800      /* underflow exception mask             */
 167 #define SSE_PM  0x00001000      /* precision exception mask             */
 168 #define SSE_RC  0x00006000      /* rounding control                     */
 169 #define SSE_RD  0x00002000      /* rounding control: round down         */
 170 #define SSE_RU  0x00004000      /* rounding control: round up           */
 171 #define SSE_FZ  0x00008000      /* flush to zero for masked underflow   */
 172 


 295         struct xsave_header     xs_header;      /* 512-575 XSAVE header */
 296         upad128_t               xs_ymm[16];     /* 576 AVX component */
 297 } __aligned(64);
 298 
 299 /*
 300  * While AVX_XSTATE_SIZE is the smallest the kernel will allocate for FPU
 301  * state-saving, other consumers may constrain themselves to the minimum
 302  * possible xsave state structure, which features only the legacy area and the
 303  * bare xsave header.
 304  */
 305 #define MIN_XSAVE_SIZE  (sizeof (struct fxsave_state) + \
 306                             sizeof (struct xsave_header))
 307 
 308 /*
 309  * Kernel's FPU save area
 310  */
 311 typedef struct {
 312         union _kfpu_u {
 313                 void *kfpu_generic;
 314                 struct fxsave_state *kfpu_fx;



 315                 struct xsave_state *kfpu_xs;
 316         } kfpu_u;
 317         uint32_t kfpu_status;           /* saved at #mf exception */
 318         uint32_t kfpu_xstatus;          /* saved at #xm exception */
 319 } kfpu_t;
 320 
 321 extern int fp_kind;             /* kind of fp support */
 322 extern int fp_save_mech;        /* fp save/restore mechanism */
 323 extern int fpu_exists;          /* FPU hw exists */
 324 extern int fp_elf;              /* FP elf type */
 325 extern uint64_t xsave_bv_all;   /* Set of enabed xcr0 values */
 326 
 327 #ifdef _KERNEL
 328 
 329 extern int fpu_ignored;
 330 extern int fpu_pentium_fdivbug;
 331 
 332 extern uint32_t sse_mxcsr_mask;
 333 
 334 extern void fpu_probe(void);
 335 extern uint_t fpu_initial_probe(void);
 336 
 337 extern void fpu_auxv_info(int *, size_t *);
 338 extern boolean_t fpu_xsave_enabled(void);
 339 
 340 extern void fpnsave_ctxt(void *);
 341 extern void fpxsave_ctxt(void *);
 342 extern void xsave_ctxt(void *);
 343 extern void xsaveopt_ctxt(void *);
 344 extern void fpxsave_excp_clr_ctxt(void *);
 345 extern void xsave_excp_clr_ctxt(void *);
 346 extern void xsaveopt_excp_clr_ctxt(void *);
 347 extern void (*fpsave_ctxt)(void *);
 348 extern void (*xsavep)(struct xsave_state *, uint64_t);
 349 
 350 extern void fpxrestore_ctxt(void *);
 351 extern void xrestore_ctxt(void *);
 352 extern void (*fprestore_ctxt)(void *);
 353 
 354 extern void fxsave_insn(struct fxsave_state *);


 355 extern void fpxsave(struct fxsave_state *);
 356 extern void fpxrestore(struct fxsave_state *);
 357 extern void xsave(struct xsave_state *, uint64_t);
 358 extern void xsaveopt(struct xsave_state *, uint64_t);
 359 extern void xrestore(struct xsave_state *, uint64_t);
 360 
 361 extern void fpenable(void);
 362 extern void fpdisable(void);
 363 extern void fpinit(void);
 364 
 365 extern uint32_t fperr_reset(void);
 366 extern uint32_t fpxerr_reset(void);
 367 
 368 extern uint32_t fpgetcwsw(void);
 369 extern uint32_t fpgetmxcsr(void);
 370 
 371 struct regs;
 372 extern int fpexterrflt(struct regs *);
 373 extern int fpsimderrflt(struct regs *);
 374 extern void fpsetcw(uint16_t, uint32_t);
 375 extern void fp_seed(void);
 376 extern void fp_exec(void);
 377 struct _klwp;
 378 extern void fp_lwp_init(struct _klwp *);
 379 extern void fp_lwp_cleanup(struct _klwp *);
 380 extern void fp_lwp_dup(struct _klwp *);
 381 
 382 extern const struct fxsave_state sse_initial;
 383 extern const struct xsave_state avx_initial;
 384 
 385 struct proc;
 386 struct ucontext;
 387 extern void fpu_proc_xregs_info(struct proc *, uint32_t *, uint32_t *,
 388     uint32_t *);
 389 extern size_t fpu_proc_xregs_max_size(void);
 390 extern void fpu_proc_xregs_get(struct _klwp *, void *);
 391 extern int fpu_proc_xregs_set(struct _klwp *, void *);
 392 extern int fpu_signal_copyin(struct _klwp *, struct ucontext *);
 393 typedef int (*fpu_copyout_f)(const void *, void *, size_t);
 394 extern int fpu_signal_copyout(struct _klwp *, uintptr_t, fpu_copyout_f);
 395 extern void fpu_set_xsave(struct _klwp *, const void *);
 396 extern size_t fpu_signal_size(struct _klwp *);
 397 
 398 extern void fpu_get_fpregset(struct _klwp *, fpregset_t *);
 399 extern void fpu_set_fpregset(struct _klwp *, const fpregset_t *);
 400 
 401 #endif  /* _KERNEL */
 402 
 403 #ifdef __cplusplus
 404 }
 405 #endif
 406 
 407 #endif  /* _SYS_FP_H */