Index: sys/amd64/amd64/fpu.c =================================================================== --- sys/amd64/amd64/fpu.c +++ sys/amd64/amd64/fpu.c @@ -100,6 +100,17 @@ "memory"); } +static __inline void +xsaveopt(char *addr, uint64_t mask) +{ + uint32_t low, hi; + + low = mask; + hi = mask >> 32; + __asm __volatile("xsaveopt %0" : "=m" (*addr) : "a" (low), "d" (hi) : + "memory"); +} + #else /* !(__GNUCLIKE_ASM && !lint) */ void fldcw(u_short cw); @@ -113,6 +124,7 @@ void stmxcsr(u_int *csr); void xrstor(char *addr, uint64_t mask); void xsave(char *addr, uint64_t mask); +void xsaveopt(char *addr, uint64_t mask); #endif /* __GNUCLIKE_ASM && !lint */ @@ -157,6 +169,13 @@ u_int size; } *xsave_area_desc; +static void +fpusave_xsaveopt(void *addr) +{ + + xsaveopt((char *)addr, xsave_mask); +} + static void fpusave_xsave(void *addr) { @@ -201,7 +220,10 @@ { init_xsave(); - return (use_xsave ? fpusave_xsave : fpusave_fxsave); + if (use_xsave) + return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ? + fpusave_xsaveopt : fpusave_xsave); + return (fpusave_fxsave); } DEFINE_IFUNC(, void, fpurestore, (void *), static) @@ -356,7 +378,7 @@ saveintr = intr_disable(); stop_emulating(); - fpusave(fpu_initialstate); + fpusave_fxsave(fpu_initialstate); if (fpu_initialstate->sv_env.en_mxcsr_mask) cpu_mxcsr_mask = fpu_initialstate->sv_env.en_mxcsr_mask; else Index: sys/i386/i386/npx.c =================================================================== --- sys/i386/i386/npx.c +++ sys/i386/i386/npx.c @@ -313,7 +313,7 @@ } static void -npxsave_xsaveopt(union savefpu *addr) +fpusave_xsaveopt(union savefpu *addr) { xsaveopt((char *)addr, xsave_mask); @@ -358,7 +358,7 @@ init_xsave(); if (use_xsave) return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ? - npxsave_xsaveopt : fpusave_xsave); + fpusave_xsaveopt : fpusave_xsave); if (cpu_fxsr) return (fpusave_fxsave); return (fpusave_fnsave); @@ -369,7 +369,8 @@ init_xsave(); if (use_xsave) - return (fpusave_xsave); + return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ? + fpusave_xsaveopt : fpusave_xsave); if (cpu_fxsr) return (fpusave_fxsave); return (fpusave_fnsave); @@ -494,7 +495,10 @@ saveintr = intr_disable(); stop_emulating(); - fpusave(npx_initialstate); + if (cpu_fxsr) + fpusave_fxsave(npx_initialstate); + else + fpusave_fnsave(npx_initialstate); if (cpu_fxsr) { if (npx_initialstate->sv_xmm.sv_env.en_mxcsr_mask) cpu_mxcsr_mask =