diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/i86pc/os/fpu_subr.c | 29 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/ml/exception.s | 12 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/ml/float.s | 79 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/archdep.c | 12 | ||||
-rw-r--r-- | usr/src/uts/intel/ia32/os/fpu.c | 93 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/archsystm.h | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/fp.h | 5 |
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; |