v->arch.vgc_flags = flags;
if ( flags & VGCF_I387_VALID )
+ {
memcpy(v->arch.fpu_ctxt, &c.nat->fpu_ctxt, sizeof(c.nat->fpu_ctxt));
+ if ( v->arch.xsave_area )
+ v->arch.xsave_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE;
+ }
if ( !compat )
{
{
struct domain *d = v->domain;
struct segment_register reg;
+ typeof(v->arch.xsave_area->fpu_sse) *fpu_ctxt = v->arch.fpu_ctxt;
domain_lock(d);
v->arch.guest_table = pagetable_null();
}
- memset(v->arch.fpu_ctxt, 0, sizeof(v->arch.xsave_area->fpu_sse));
+ memset(fpu_ctxt, 0, sizeof(*fpu_ctxt));
+ fpu_ctxt->fcw = FCW_RESET;
+ fpu_ctxt->mxcsr = MXCSR_DEFAULT;
+ if ( v->arch.xsave_area )
+ v->arch.xsave_area->xsave_hdr.xstate_bv = XSTATE_FP;
+
v->arch.vgc_flags = VGCF_online;
memset(&v->arch.user_regs, 0, sizeof(v->arch.user_regs));
v->arch.user_regs.eflags = 2;
if ( save_area == NULL )
return -ENOMEM;
+ /*
+ * Set the memory image to default values, but don't force the context
+ * to be loaded from memory (i.e. keep save_area->xsave_hdr.xstate_bv
+ * clear).
+ */
save_area->fpu_sse.fcw = FCW_DEFAULT;
save_area->fpu_sse.mxcsr = MXCSR_DEFAULT;
- save_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE;
v->arch.xsave_area = save_area;
v->arch.xcr0 = XSTATE_FP_SSE;
#include <xen/types.h>
#define FCW_DEFAULT 0x037f
+#define FCW_RESET 0x0040
#define MXCSR_DEFAULT 0x1f80
#define XSTATE_CPUID 0x0000000d