summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/sys/fp.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/sys/fp.h')
-rw-r--r--usr/src/uts/intel/sys/fp.h65
1 files changed, 54 insertions, 11 deletions
diff --git a/usr/src/uts/intel/sys/fp.h b/usr/src/uts/intel/sys/fp.h
index 3373484dec..e6d482fdd8 100644
--- a/usr/src/uts/intel/sys/fp.h
+++ b/usr/src/uts/intel/sys/fp.h
@@ -20,6 +20,7 @@
*/
/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
*
* Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -229,27 +230,59 @@ struct fxsave_state {
}; /* 512 bytes */
/*
- * This structure is written to memory by an 'xsave' instruction.
- * First 512 byte is compatible with the format of an 'fxsave' area.
+ * This structure is written to memory by one of the 'xsave' instruction
+ * variants. The first 512 bytes are compatible with the format of the 'fxsave'
+ * area. The header portion of the xsave layout is documented in section
+ * 13.4.2 of the Intel 64 and IA-32 Architectures Software Developer’s Manual,
+ * Volume 1 (IASDv1). The extended portion is documented in section 13.4.3.
+ *
+ * Our size is at least AVX_XSAVE_SIZE (832 bytes), asserted in fpnoextflt().
+ * Enabling additional xsave-related CPU features requires an increase in the
+ * size. We dynamically allocate the per-lwp xsave area at runtime, based on
+ * the size needed for the CPU-specific features. This xsave_state structure
+ * simply defines our historical layout for the beginning of the xsave area. The
+ * locations and size of new, extended, components is determined dynamically by
+ * querying the CPU. See the xsave_info structure in cpuid.c.
+ *
+ * xsave component usage is tracked using bits in the xs_xstate_bv field. The
+ * components are documented in section 13.1 of IASDv1. For easy reference,
+ * this is a summary of the currently defined component bit definitions:
+ * x87 0x0001
+ * SSE 0x0002
+ * AVX 0x0004
+ * bndreg (MPX) 0x0008
+ * bndcsr (MPX) 0x0010
+ * opmask (AVX512) 0x0020
+ * zmm hi256 (AVX512) 0x0040
+ * zmm hi16 (AVX512) 0x0080
+ * PT 0x0100
+ * PKRU 0x0200
+ * When xsaveopt_ctxt is being used to save into the xsave_state area, the
+ * xs_xstate_bv field is updated by the xsaveopt instruction to indicate which
+ * elements of the xsave area are active.
+ *
+ * xs_xcomp_bv should always be 0, since we do not currently use the compressed
+ * form of xsave (xsavec).
*/
struct xsave_state {
- struct fxsave_state xs_fxsave;
- uint64_t xs_xstate_bv; /* 512 */
- uint64_t xs_rsv_mbz[2];
- uint64_t xs_reserved[5];
- upad128_t xs_ymm[16]; /* avx - 576 */
-}; /* 832 bytes, asserted in fpnoextflt() */
+ struct fxsave_state xs_fxsave; /* 0-511 legacy region */
+ uint64_t xs_xstate_bv; /* 512-519 start xsave header */
+ uint64_t xs_xcomp_bv; /* 520-527 */
+ uint64_t xs_reserved[6]; /* 528-575 end xsave header */
+ upad128_t xs_ymm[16]; /* 576 AVX component */
+};
/*
* Kernel's FPU save area
*/
typedef struct {
union _kfpu_u {
- struct fxsave_state kfpu_fx;
+ void *kfpu_generic;
+ struct fxsave_state *kfpu_fx;
#if defined(__i386)
- struct fnsave_state kfpu_fn;
+ struct fnsave_state *kfpu_fn;
#endif
- struct xsave_state kfpu_xs;
+ struct xsave_state *kfpu_xs;
} kfpu_u;
uint32_t kfpu_status; /* saved at #mf exception */
uint32_t kfpu_xstatus; /* saved at #xm exception */
@@ -273,7 +306,12 @@ extern int fpu_probe_pentium_fdivbug(void);
extern void fpnsave_ctxt(void *);
extern void fpxsave_ctxt(void *);
extern void xsave_ctxt(void *);
+extern void xsaveopt_ctxt(void *);
+extern void fpxsave_excp_clr_ctxt(void *);
+extern void xsave_excp_clr_ctxt(void *);
+extern void xsaveopt_excp_clr_ctxt(void *);
extern void (*fpsave_ctxt)(void *);
+extern void (*xsavep)(struct xsave_state *, uint64_t);
extern void fxsave_insn(struct fxsave_state *);
extern void fpsave(struct fnsave_state *);
@@ -281,6 +319,7 @@ 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);
extern void fpenable(void);
@@ -299,6 +338,10 @@ extern int fpextovrflt(struct regs *);
extern int fpexterrflt(struct regs *);
extern int fpsimderrflt(struct regs *);
extern void fpsetcw(uint16_t, uint32_t);
+struct _klwp;
+extern void fp_lwp_init(struct _klwp *);
+extern void fp_lwp_cleanup(struct _klwp *);
+extern void fp_lwp_dup(struct _klwp *);
#endif /* _KERNEL */