aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/i387.c
diff options
context:
space:
mode:
Diffstat (limited to 'xen/arch/x86/i387.c')
-rw-r--r--xen/arch/x86/i387.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
index a05522414c..7c1feb6ac1 100644
--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -38,14 +38,15 @@ static inline void fpu_xrstor(struct vcpu *v, uint64_t mask)
{
bool_t ok;
+ ASSERT(v->arch.xsave_area);
/*
* XCR0 normally represents what guest OS set. In case of Xen itself,
- * we set all supported feature mask before doing save/restore.
+ * we set the accumulated feature mask before doing save/restore.
*/
- ok = set_xcr0(v->arch.xcr0_accum);
+ ok = set_xcr0(v->arch.xcr0_accum | XSTATE_FP_SSE);
ASSERT(ok);
xrstor(v, mask);
- ok = set_xcr0(v->arch.xcr0);
+ ok = set_xcr0(v->arch.xcr0 ?: XSTATE_FP_SSE);
ASSERT(ok);
}
@@ -126,13 +127,15 @@ static inline void fpu_xsave(struct vcpu *v)
{
bool_t ok;
- /* XCR0 normally represents what guest OS set. In case of Xen itself,
- * we set all accumulated feature mask before doing save/restore.
+ ASSERT(v->arch.xsave_area);
+ /*
+ * XCR0 normally represents what guest OS set. In case of Xen itself,
+ * we set the accumulated feature mask before doing save/restore.
*/
- ok = set_xcr0(v->arch.xcr0_accum);
+ ok = set_xcr0(v->arch.xcr0_accum | XSTATE_FP_SSE);
ASSERT(ok);
xsave(v, v->arch.nonlazy_xstate_used ? XSTATE_ALL : XSTATE_LAZY);
- ok = set_xcr0(v->arch.xcr0);
+ ok = set_xcr0(v->arch.xcr0 ?: XSTATE_FP_SSE);
ASSERT(ok);
}
@@ -242,7 +245,7 @@ void vcpu_restore_fpu_lazy(struct vcpu *v)
if ( v->fpu_dirtied )
return;
- if ( xsave_enabled(v) )
+ if ( cpu_has_xsave )
fpu_xrstor(v, XSTATE_LAZY);
else if ( v->fpu_initialised )
{
@@ -272,7 +275,7 @@ void vcpu_save_fpu(struct vcpu *v)
/* This can happen, if a paravirtualised guest OS has set its CR0.TS. */
clts();
- if ( xsave_enabled(v) )
+ if ( cpu_has_xsave )
fpu_xsave(v);
else if ( cpu_has_fxsr )
fpu_fxsave(v);