summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/i86pc/os/fpu_subr.c29
-rw-r--r--usr/src/uts/intel/ia32/ml/exception.s12
-rw-r--r--usr/src/uts/intel/ia32/ml/float.s79
-rw-r--r--usr/src/uts/intel/ia32/os/archdep.c12
-rw-r--r--usr/src/uts/intel/ia32/os/fpu.c93
-rw-r--r--usr/src/uts/intel/sys/archsystm.h2
-rw-r--r--usr/src/uts/intel/sys/fp.h5
7 files changed, 130 insertions, 102 deletions
diff --git a/usr/src/uts/i86pc/os/fpu_subr.c b/usr/src/uts/i86pc/os/fpu_subr.c
index b661ecd1a7..e65c65de92 100644
--- a/usr/src/uts/i86pc/os/fpu_subr.c
+++ b/usr/src/uts/i86pc/os/fpu_subr.c
@@ -39,6 +39,12 @@
#define XMM_ALIGN 16
/*
+ * See section 10.5.1 in the Intel 64 and IA-32 Architectures Software
+ * Developer’s Manual, Volume 1.
+ */
+#define FXSAVE_ALIGN 16
+
+/*
* See section 13.4 in the Intel 64 and IA-32 Architectures Software
* Developer’s Manual, Volume 1.
*/
@@ -170,9 +176,15 @@ fpu_probe(void)
fp_save_mech = FP_XSAVE;
fpsave_ctxt = xsave_ctxt;
patch_xsave();
- xsave_cachep = kmem_cache_create("xsave_cache",
+ fpsave_cachep = kmem_cache_create("xsave_cache",
cpuid_get_xsave_size(), XSAVE_ALIGN,
NULL, NULL, NULL, NULL, NULL, 0);
+ } else {
+ /* fp_save_mech defaults to FP_FXSAVE */
+ fpsave_cachep =
+ kmem_cache_create("fxsave_cache",
+ sizeof (struct fxsave_state), FXSAVE_ALIGN,
+ NULL, NULL, NULL, NULL, NULL, 0);
}
}
#elif defined(__i386)
@@ -200,11 +212,15 @@ fpu_probe(void)
fp_save_mech = FP_XSAVE;
fpsave_ctxt = xsave_ctxt;
patch_xsave();
- xsave_cachep = kmem_cache_create("xsave_cache",
+ fpsave_cachep = kmem_cache_create("xsave_cache",
cpuid_get_xsave_size(), XSAVE_ALIGN,
NULL, NULL, NULL, NULL, NULL, 0);
} else {
patch_sse(); /* use fxrstor */
+ fpsave_cachep =
+ kmem_cache_create("fxsave_cache",
+ sizeof (struct fxsave_state), FXSAVE_ALIGN,
+ NULL, NULL, NULL, NULL, NULL, 0);
}
} else {
remove_x86_feature(x86_featureset, X86FSET_SSE2);
@@ -219,6 +235,15 @@ fpu_probe(void)
* enabled when we didn't. See 4965674.)
*/
DISABLE_SSE();
+
+ /*
+ * fp_save_mech defaults to FP_FNSAVE. Use the same
+ * alignment as used for fxsave (preserves legacy
+ * behavior).
+ */
+ fpsave_cachep = kmem_cache_create("fnsave_cache",
+ sizeof (struct fnsave_state), FXSAVE_ALIGN,
+ NULL, NULL, NULL, NULL, NULL, 0);
}
#endif
if (is_x86_feature(x86_featureset, X86FSET_SSE2)) {
diff --git a/usr/src/uts/intel/ia32/ml/exception.s b/usr/src/uts/intel/ia32/ml/exception.s
index 5855ef4b81..c6e2250f4e 100644
--- a/usr/src/uts/intel/ia32/ml/exception.s
+++ b/usr/src/uts/intel/ia32/ml/exception.s
@@ -666,11 +666,9 @@ _emul_done:
* kernel due to user fault.
*/
ALTENTRY(ndptrap_frstor)
+ movq (%rbx), %rbx /* fpu_regs.kfpu_u.kfpu_XX pointer */
.globl _patch_xrstorq_rbx
_patch_xrstorq_rbx:
- nop
- nop
- nop
FXRSTORQ ((%rbx))
cmpw $KCS_SEL, REGOFF_CS(%rsp)
je .return_to_kernel
@@ -744,11 +742,9 @@ _patch_xrstorq_rbx:
* kernel due to user fault.
*/
ALTENTRY(ndptrap_frstor)
+ movq (%rbx), %rbx /* fpu_regs.kfpu_u.kfpu_XX pointer */
.globl _patch_xrstorq_rbx
_patch_xrstorq_rbx:
- nop
- nop
- nop
FXRSTORQ ((%rbx))
popq %rdx
popq %rbx
@@ -811,14 +807,12 @@ _patch_xrstorq_rbx:
* due to user fault.
*/
ALTENTRY(ndptrap_frstor)
+ movl (%ebx), %ebx /* fpu_regs.kfpu_u.kfpu_XX pointer */
.globl _patch_fxrstor_ebx
_patch_fxrstor_ebx:
.globl _patch_xrstor_ebx
_patch_xrstor_ebx:
frstor (%ebx) /* may be patched to fxrstor or xrstor */
- nop /* (including these bytes) */
- nop
- nop
popl %gs
popl %ds
popl %edx
diff --git a/usr/src/uts/intel/ia32/ml/float.s b/usr/src/uts/intel/ia32/ml/float.s
index b173108591..cfc134b219 100644
--- a/usr/src/uts/intel/ia32/ml/float.s
+++ b/usr/src/uts/intel/ia32/ml/float.s
@@ -178,7 +178,7 @@ _fxrstor_ebx_insn: / see ndptrap_frstor()
_ldmxcsr_ebx_insn: / see resume_from_zombie()
ldmxcsr (%ebx)
_sfence_ret_insn: / see membar_producer()
- .byte 0xf, 0xae, 0xf8 / [sfence instruction]
+ sfence
ret
SET_SIZE(patch_sse)
@@ -191,7 +191,7 @@ _sfence_ret_insn: / see membar_producer()
_HOT_PATCH_EPILOG
ret
_lfence_ret_insn: / see membar_consumer()
- .byte 0xf, 0xae, 0xe8 / [lfence instruction]
+ lfence
ret
SET_SIZE(patch_sse2)
@@ -204,13 +204,11 @@ _lfence_ret_insn: / see membar_consumer()
/
/ frstor (%ebx); nop -> xrstor (%ebx)
/
- _HOT_PATCH(_xrstor_ebx_insn, _patch_xrstor_ebx, 5)
+ _HOT_PATCH(_xrstor_ebx_insn, _patch_xrstor_ebx, 3)
_HOT_PATCH_EPILOG
ret
_xrstor_ebx_insn: / see ndptrap_frstor()
- movl (%ebx), %ebx
- #xrstor (%ebx)
- .byte 0x0f, 0xae, 0x2b
+ xrstor (%ebx)
SET_SIZE(patch_xsave)
#endif /* __lint */
@@ -234,14 +232,13 @@ patch_xsave(void)
pushq %rbp
pushq %r15
/
- / nop; nop; nop; -> movq(%rbx), %rbx
- / FXRSTORQ (%rbx); -> xrstor (%rbx)
- / loop doing the following for 7 bytes:
+ / FXRSTORQ (%rbx); -> nop; xrstor (%rbx)
+ / loop doing the following for 4 bytes:
/ hot_patch_kernel_text(_patch_xrstorq_rbx, _xrstor_rbx_insn, 1)
/
leaq _patch_xrstorq_rbx(%rip), %rbx
leaq _xrstor_rbx_insn(%rip), %rbp
- movq $7, %r15
+ movq $4, %r15
1:
movq %rbx, %rdi /* patch address */
movzbq (%rbp), %rsi /* instruction byte */
@@ -251,17 +248,18 @@ patch_xsave(void)
addq $1, %rbp
subq $1, %r15
jnz 1b
-
+
popq %r15
popq %rbp
popq %rbx
ret
_xrstor_rbx_insn: / see ndptrap_frstor()
- movq (%rbx), %rbx
- #rex.W=1 (.byte 0x48)
- #xrstor (%rbx)
- .byte 0x48, 0x0f, 0xae, 0x2b
+ # Because the FXRSTORQ macro we're patching is 4 bytes long, due
+ # to the 0x48 prefix (indicating 64-bit operand size), we patch 4 bytes
+ # too.
+ nop
+ xrstor (%rbx)
SET_SIZE(patch_xsave)
#endif /* __lint */
@@ -293,12 +291,13 @@ fpnsave_ctxt(void *arg)
#if defined(__amd64)
- ENTRY_NP(fpxsave_ctxt)
+ ENTRY_NP(fpxsave_ctxt) /* %rdi is a struct fpu_ctx */
cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%rdi)
jne 1f
movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%rdi)
- FXSAVEQ (FPU_CTX_FPU_REGS(%rdi))
+ movq FPU_CTX_FPU_REGS(%rdi), %rdi /* fpu_regs.kfpu_u.kfpu_fn ptr */
+ FXSAVEQ ((%rdi))
/*
* On certain AMD processors, the "exception pointers" i.e. the last
@@ -331,11 +330,9 @@ fpnsave_ctxt(void *arg)
*/
movl FPU_CTX_FPU_XSAVE_MASK(%rdi), %eax
movl FPU_CTX_FPU_XSAVE_MASK+4(%rdi), %edx
- leaq FPU_CTX_FPU_REGS(%rdi), %rsi
- movq (%rsi), %rsi /* load fpu_regs.kfpu_u.kfpu_xs pointer */
- #xsave (%rsi)
- .byte 0x0f, 0xae, 0x26
-
+ movq FPU_CTX_FPU_REGS(%rdi), %rsi /* fpu_regs.kfpu_u.kfpu_xs ptr */
+ xsave (%rsi)
+
/*
* (see notes above about "exception pointers")
* TODO: does it apply to any machine that uses xsave?
@@ -358,7 +355,8 @@ fpnsave_ctxt(void *arg)
jne 1f
movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax)
- fnsave FPU_CTX_FPU_REGS(%eax)
+ movl FPU_CTX_FPU_REGS(%eax), %eax /* fpu_regs.kfpu_u.kfpu_fx ptr */
+ fnsave (%eax)
/* (fnsave also reinitializes x87 state) */
STTS(%edx) /* trap on next fpu touch */
1: rep; ret /* use 2 byte return instruction when branch target */
@@ -371,7 +369,8 @@ fpnsave_ctxt(void *arg)
jne 1f
movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%eax)
- fxsave FPU_CTX_FPU_REGS(%eax)
+ movl FPU_CTX_FPU_REGS(%eax), %eax /* fpu_regs.kfpu_u.kfpu_fn ptr */
+ fxsave (%eax)
/* (see notes above about "exception pointers") */
btw $7, FXSAVE_STATE_FSW(%eax) /* Test saved ES bit */
jnc 0f /* jump if ES = 0 */
@@ -388,15 +387,13 @@ fpnsave_ctxt(void *arg)
movl 4(%esp), %ecx /* a struct fpu_ctx */
cmpl $FPU_EN, FPU_CTX_FPU_FLAGS(%ecx)
jne 1f
-
+
movl $_CONST(FPU_VALID|FPU_EN), FPU_CTX_FPU_FLAGS(%ecx)
movl FPU_CTX_FPU_XSAVE_MASK(%ecx), %eax
movl FPU_CTX_FPU_XSAVE_MASK+4(%ecx), %edx
- leal FPU_CTX_FPU_REGS(%ecx), %ecx
- movl (%ecx), %ecx /* load fpu_regs.kfpu_u.kfpu_xs pointer */
- #xsave (%ecx)
- .byte 0x0f, 0xae, 0x21
-
+ movl FPU_CTX_FPU_REGS(%ecx), %ecx /* fpu_regs.kfpu_u.kfpu_xs ptr */
+ xsave (%ecx)
+
/*
* (see notes above about "exception pointers")
* TODO: does it apply to any machine that uses xsave?
@@ -455,9 +452,8 @@ xsave(struct xsave_state *f, uint64_t m)
movl %esi, %eax /* bv mask */
movq %rsi, %rdx
shrq $32, %rdx
- #xsave (%rdi)
- .byte 0x0f, 0xae, 0x27
-
+ xsave (%rdi)
+
fninit /* clear exceptions, init x87 tags */
STTS(%rdi) /* set TS bit in %cr0 (disable FPU) */
ret
@@ -487,9 +483,8 @@ xsave(struct xsave_state *f, uint64_t m)
movl 4(%esp), %ecx
movl 8(%esp), %eax
movl 12(%esp), %edx
- #xsave (%ecx)
- .byte 0x0f, 0xae, 0x21
-
+ xsave (%ecx)
+
fninit /* clear exceptions, init x87 tags */
STTS(%eax) /* set TS bit in %cr0 (disable FPU) */
ret
@@ -530,8 +525,7 @@ xrestore(struct xsave_state *f, uint64_t m)
movl %esi, %eax /* bv mask */
movq %rsi, %rdx
shrq $32, %rdx
- #xrstor (%rdi)
- .byte 0x0f, 0xae, 0x2f
+ xrstor (%rdi)
ret
SET_SIZE(xrestore)
@@ -556,8 +550,7 @@ xrestore(struct xsave_state *f, uint64_t m)
movl 4(%esp), %ecx
movl 8(%esp), %eax
movl 12(%esp), %edx
- #xrstor (%ecx)
- .byte 0x0f, 0xae, 0x29
+ xrstor (%ecx)
ret
SET_SIZE(xrestore)
@@ -624,8 +617,7 @@ fpinit(void)
bt $X86FSET_AVX, x86_featureset
cmovael %edx, %eax
orl $(XFEATURE_LEGACY_FP | XFEATURE_SSE), %eax
- /* xrstor (%rcx) */
- .byte 0x0f, 0xae, 0x29 /* load clean initial state */
+ xrstor (%rcx)
ret
SET_SIZE(fpinit)
@@ -656,8 +648,7 @@ fpinit(void)
bt $X86FSET_AVX, x86_featureset
cmovael %edx, %eax
orl $(XFEATURE_LEGACY_FP | XFEATURE_SSE), %eax
- /* xrstor (%ecx) */
- .byte 0x0f, 0xae, 0x29 /* load clean initial state */
+ xrstor (%ecx)
ret
SET_SIZE(fpinit)
diff --git a/usr/src/uts/intel/ia32/os/archdep.c b/usr/src/uts/intel/ia32/os/archdep.c
index d8b4f5d6e8..fa65b59267 100644
--- a/usr/src/uts/intel/ia32/os/archdep.c
+++ b/usr/src/uts/intel/ia32/os/archdep.c
@@ -295,12 +295,12 @@ setfpregs(klwp_t *lwp, fpregset_t *fp)
switch (fp_save_mech) {
#if defined(__i386)
case FP_FNSAVE:
- bcopy(fp, &fpu->fpu_regs.kfpu_u.kfpu_fn,
- sizeof (fpu->fpu_regs.kfpu_u.kfpu_fn));
+ bcopy(fp, fpu->fpu_regs.kfpu_u.kfpu_fn,
+ sizeof (*fpu->fpu_regs.kfpu_u.kfpu_fn));
break;
#endif
case FP_FXSAVE:
- fpregset_to_fxsave(fp, &fpu->fpu_regs.kfpu_u.kfpu_fx);
+ fpregset_to_fxsave(fp, fpu->fpu_regs.kfpu_u.kfpu_fx);
fpu->fpu_regs.kfpu_xstatus =
fp->fp_reg_set.fpchip_state.xstatus;
break;
@@ -359,12 +359,12 @@ getfpregs(klwp_t *lwp, fpregset_t *fp)
switch (fp_save_mech) {
#if defined(__i386)
case FP_FNSAVE:
- bcopy(&fpu->fpu_regs.kfpu_u.kfpu_fn, fp,
- sizeof (fpu->fpu_regs.kfpu_u.kfpu_fn));
+ bcopy(fpu->fpu_regs.kfpu_u.kfpu_fn, fp,
+ sizeof (*fpu->fpu_regs.kfpu_u.kfpu_fn));
break;
#endif
case FP_FXSAVE:
- fxsave_to_fpregset(&fpu->fpu_regs.kfpu_u.kfpu_fx, fp);
+ fxsave_to_fpregset(fpu->fpu_regs.kfpu_u.kfpu_fx, fp);
fp->fp_reg_set.fpchip_state.xstatus =
fpu->fpu_regs.kfpu_xstatus;
break;
diff --git a/usr/src/uts/intel/ia32/os/fpu.c b/usr/src/uts/intel/ia32/os/fpu.c
index ebaaa25c66..33cd6b2e87 100644
--- a/usr/src/uts/intel/ia32/os/fpu.c
+++ b/usr/src/uts/intel/ia32/os/fpu.c
@@ -61,7 +61,7 @@
#include <sys/sysmacros.h>
#include <sys/cmn_err.h>
-kmem_cache_t *xsave_cachep;
+kmem_cache_t *fpsave_cachep;
/* Legacy fxsave layout + xsave header + ymm */
#define AVX_XSAVE_SIZE (512 + 64 + 256)
@@ -205,15 +205,15 @@ fp_new_lwp(kthread_id_t t, kthread_id_t ct)
switch (fp_save_mech) {
#if defined(__i386)
case FP_FNSAVE:
- fn = &fp->fpu_regs.kfpu_u.kfpu_fn;
- cfn = &cfp->fpu_regs.kfpu_u.kfpu_fn;
+ fn = fp->fpu_regs.kfpu_u.kfpu_fn;
+ cfn = cfp->fpu_regs.kfpu_u.kfpu_fn;
bcopy(&x87_initial, cfn, sizeof (*cfn));
cfn->f_fcw = fn->f_fcw;
break;
#endif
case FP_FXSAVE:
- fx = &fp->fpu_regs.kfpu_u.kfpu_fx;
- cfx = &cfp->fpu_regs.kfpu_u.kfpu_fx;
+ fx = fp->fpu_regs.kfpu_u.kfpu_fx;
+ cfx = cfp->fpu_regs.kfpu_u.kfpu_fx;
bcopy(&sse_initial, cfx, sizeof (*cfx));
cfx->fx_mxcsr = fx->fx_mxcsr & ~SSE_MXCSR_EFLAGS;
cfx->fx_fcw = fx->fx_fcw;
@@ -310,11 +310,11 @@ fp_save(struct fpu_ctx *fp)
switch (fp_save_mech) {
#if defined(__i386)
case FP_FNSAVE:
- fpsave(&fp->fpu_regs.kfpu_u.kfpu_fn);
+ fpsave(fp->fpu_regs.kfpu_u.kfpu_fn);
break;
#endif
case FP_FXSAVE:
- fpxsave(&fp->fpu_regs.kfpu_u.kfpu_fx);
+ fpxsave(fp->fpu_regs.kfpu_u.kfpu_fx);
break;
case FP_XSAVE:
@@ -341,11 +341,11 @@ fp_restore(struct fpu_ctx *fp)
switch (fp_save_mech) {
#if defined(__i386)
case FP_FNSAVE:
- fprestore(&fp->fpu_regs.kfpu_u.kfpu_fn);
+ fprestore(fp->fpu_regs.kfpu_u.kfpu_fn);
break;
#endif
case FP_FXSAVE:
- fpxrestore(&fp->fpu_regs.kfpu_u.kfpu_fx);
+ fpxrestore(fp->fpu_regs.kfpu_u.kfpu_fx);
break;
case FP_XSAVE:
@@ -404,21 +404,22 @@ fp_seed(void)
void
fp_lwp_init(struct _klwp *lwp)
{
- if (fp_save_mech == FP_XSAVE) {
- struct fpu_ctx *fp = &lwp->lwp_pcb.pcb_fpu;
+ struct fpu_ctx *fp = &lwp->lwp_pcb.pcb_fpu;
- ASSERT(cpuid_get_xsave_size() >= sizeof (struct xsave_state));
+ /*
+ * We keep a copy of the pointer in lwp_fpu so that we can restore the
+ * value in forklwp() after we duplicate the parent's LWP state.
+ */
+ lwp->lwp_fpu = fp->fpu_regs.kfpu_u.kfpu_generic =
+ kmem_cache_alloc(fpsave_cachep, KM_SLEEP);
+ if (fp_save_mech == FP_XSAVE) {
/*
- * We keep a copy of the pointer in lwp_fpu so that we can
- * restore the value in forklwp() after we duplicate the
- * parent's LWP state.
*
* We bzero since the fpinit() code path will only
* partially initialize the xsave area using avx_inital.
*/
- lwp->lwp_fpu = fp->fpu_regs.kfpu_u.kfpu_xs =
- kmem_cache_alloc(xsave_cachep, KM_SLEEP);
+ ASSERT(cpuid_get_xsave_size() >= sizeof (struct xsave_state));
bzero(fp->fpu_regs.kfpu_u.kfpu_xs, cpuid_get_xsave_size());
}
}
@@ -428,29 +429,45 @@ fp_lwp_cleanup(struct _klwp *lwp)
{
struct fpu_ctx *fp = &lwp->lwp_pcb.pcb_fpu;
- if (fp_save_mech == FP_XSAVE && fp->fpu_regs.kfpu_u.kfpu_xs != NULL) {
- kmem_cache_free(xsave_cachep, fp->fpu_regs.kfpu_u.kfpu_xs);
- lwp->lwp_fpu = fp->fpu_regs.kfpu_u.kfpu_xs = NULL;
+ if (fp->fpu_regs.kfpu_u.kfpu_generic != NULL) {
+ kmem_cache_free(fpsave_cachep,
+ fp->fpu_regs.kfpu_u.kfpu_generic);
+ lwp->lwp_fpu = fp->fpu_regs.kfpu_u.kfpu_generic = NULL;
}
}
/*
- * Called during the process of forklwp(). The xsave pointer may have been
+ * Called during the process of forklwp(). The kfpu_u pointer will have been
* overwritten while copying the parent's LWP structure. We have a valid copy
* stashed in the child's lwp_fpu which we use to restore the correct value.
*/
void
fp_lwp_dup(struct _klwp *lwp)
{
- if (fp_save_mech == FP_XSAVE) {
- struct xsave_state *xp = (struct xsave_state *)lwp->lwp_fpu;
+ void *xp = lwp->lwp_fpu;
+ size_t sz;
- /* copy the parent's values into the new lwp's struct */
- bcopy(lwp->lwp_pcb.pcb_fpu.fpu_regs.kfpu_u.kfpu_xs,
- xp, cpuid_get_xsave_size());
- /* now restore the pointer */
- lwp->lwp_pcb.pcb_fpu.fpu_regs.kfpu_u.kfpu_xs = xp;
+ switch (fp_save_mech) {
+#if defined(__i386)
+ case FP_FNSAVE:
+ sz = sizeof (struct fnsave_state);
+ break;
+#endif
+ case FP_FXSAVE:
+ sz = sizeof (struct fxsave_state);
+ break;
+ case FP_XSAVE:
+ sz = cpuid_get_xsave_size();
+ break;
+ default:
+ panic("Invalid fp_save_mech");
+ /*NOTREACHED*/
}
+
+ /* copy the parent's values into the new lwp's struct */
+ bcopy(lwp->lwp_pcb.pcb_fpu.fpu_regs.kfpu_u.kfpu_generic, xp, sz);
+ /* now restore the pointer */
+ lwp->lwp_pcb.pcb_fpu.fpu_regs.kfpu_u.kfpu_generic = xp;
}
@@ -603,16 +620,16 @@ fpexterrflt(struct regs *rp)
switch (fp_save_mech) {
#if defined(__i386)
case FP_FNSAVE:
- fpsw = fp->fpu_regs.kfpu_u.kfpu_fn.f_fsw;
- fpcw = fp->fpu_regs.kfpu_u.kfpu_fn.f_fcw;
- fp->fpu_regs.kfpu_u.kfpu_fn.f_fsw &= ~FPS_SW_EFLAGS;
+ fpsw = fp->fpu_regs.kfpu_u.kfpu_fn->f_fsw;
+ fpcw = fp->fpu_regs.kfpu_u.kfpu_fn->f_fcw;
+ fp->fpu_regs.kfpu_u.kfpu_fn->f_fsw &= ~FPS_SW_EFLAGS;
break;
#endif
case FP_FXSAVE:
- fpsw = fp->fpu_regs.kfpu_u.kfpu_fx.fx_fsw;
- fpcw = fp->fpu_regs.kfpu_u.kfpu_fx.fx_fcw;
- fp->fpu_regs.kfpu_u.kfpu_fx.fx_fsw &= ~FPS_SW_EFLAGS;
+ fpsw = fp->fpu_regs.kfpu_u.kfpu_fx->fx_fsw;
+ fpcw = fp->fpu_regs.kfpu_u.kfpu_fx->fx_fcw;
+ fp->fpu_regs.kfpu_u.kfpu_fx->fx_fsw &= ~FPS_SW_EFLAGS;
break;
case FP_XSAVE:
@@ -682,8 +699,8 @@ fpsimderrflt(struct regs *rp)
fp->fpu_regs.kfpu_status =
fp->fpu_regs.kfpu_u.kfpu_xs->xs_fxsave.fx_fsw;
} else {
- mxcsr = fp->fpu_regs.kfpu_u.kfpu_fx.fx_mxcsr;
- fp->fpu_regs.kfpu_status = fp->fpu_regs.kfpu_u.kfpu_fx.fx_fsw;
+ mxcsr = fp->fpu_regs.kfpu_u.kfpu_fx->fx_mxcsr;
+ fp->fpu_regs.kfpu_status = fp->fpu_regs.kfpu_u.kfpu_fx->fx_fsw;
}
fp->fpu_regs.kfpu_xstatus = mxcsr;
@@ -792,11 +809,11 @@ fpsetcw(uint16_t fcw, uint32_t mxcsr)
switch (fp_save_mech) {
#if defined(__i386)
case FP_FNSAVE:
- fp->fpu_regs.kfpu_u.kfpu_fn.f_fcw = fcw;
+ fp->fpu_regs.kfpu_u.kfpu_fn->f_fcw = fcw;
break;
#endif
case FP_FXSAVE:
- fx = &fp->fpu_regs.kfpu_u.kfpu_fx;
+ fx = fp->fpu_regs.kfpu_u.kfpu_fx;
fx->fx_fcw = fcw;
fx->fx_mxcsr = sse_mxcsr_mask & mxcsr;
break;
diff --git a/usr/src/uts/intel/sys/archsystm.h b/usr/src/uts/intel/sys/archsystm.h
index 80b860f2d0..9cfd83a334 100644
--- a/usr/src/uts/intel/sys/archsystm.h
+++ b/usr/src/uts/intel/sys/archsystm.h
@@ -60,7 +60,7 @@ extern void patch_sse2(void);
#endif
extern void patch_xsave(void);
-extern kmem_cache_t *xsave_cachep;
+extern kmem_cache_t *fpsave_cachep;
extern void cli(void);
extern void sti(void);
diff --git a/usr/src/uts/intel/sys/fp.h b/usr/src/uts/intel/sys/fp.h
index e785838bba..9e1c3a486e 100644
--- a/usr/src/uts/intel/sys/fp.h
+++ b/usr/src/uts/intel/sys/fp.h
@@ -254,9 +254,10 @@ struct xsave_state {
*/
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;
} kfpu_u;