90 lines
2.5 KiB
Diff
90 lines
2.5 KiB
Diff
|
x86: don't leak ST(n)/XMMn values to domains first using them
|
||
|
|
||
|
FNINIT doesn't alter these registers, and hence using it is
|
||
|
insufficient to initialize a guest's initial state.
|
||
|
|
||
|
This is XSA-165.
|
||
|
|
||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||
|
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
||
|
|
||
|
Index: xen-4.6.0-testing/xen/arch/x86/domain.c
|
||
|
===================================================================
|
||
|
--- xen-4.6.0-testing.orig/xen/arch/x86/domain.c
|
||
|
+++ xen-4.6.0-testing/xen/arch/x86/domain.c
|
||
|
@@ -851,6 +851,17 @@ int arch_set_info_guest(
|
||
|
if ( v->arch.xsave_area )
|
||
|
v->arch.xsave_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE;
|
||
|
}
|
||
|
+ else if ( v->arch.xsave_area )
|
||
|
+ memset(&v->arch.xsave_area->xsave_hdr, 0,
|
||
|
+ sizeof(v->arch.xsave_area->xsave_hdr));
|
||
|
+ else
|
||
|
+ {
|
||
|
+ typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt;
|
||
|
+
|
||
|
+ memset(fpu_sse, 0, sizeof(*fpu_sse));
|
||
|
+ fpu_sse->fcw = FCW_DEFAULT;
|
||
|
+ fpu_sse->mxcsr = MXCSR_DEFAULT;
|
||
|
+ }
|
||
|
|
||
|
if ( !compat )
|
||
|
{
|
||
|
Index: xen-4.6.0-testing/xen/arch/x86/i387.c
|
||
|
===================================================================
|
||
|
--- xen-4.6.0-testing.orig/xen/arch/x86/i387.c
|
||
|
+++ xen-4.6.0-testing/xen/arch/x86/i387.c
|
||
|
@@ -17,19 +17,6 @@
|
||
|
#include <asm/xstate.h>
|
||
|
#include <asm/asm_defns.h>
|
||
|
|
||
|
-static void fpu_init(void)
|
||
|
-{
|
||
|
- unsigned long val;
|
||
|
-
|
||
|
- asm volatile ( "fninit" );
|
||
|
- if ( cpu_has_xmm )
|
||
|
- {
|
||
|
- /* load default value into MXCSR control/status register */
|
||
|
- val = MXCSR_DEFAULT;
|
||
|
- asm volatile ( "ldmxcsr %0" : : "m" (val) );
|
||
|
- }
|
||
|
-}
|
||
|
-
|
||
|
/*******************************/
|
||
|
/* FPU Restore Functions */
|
||
|
/*******************************/
|
||
|
@@ -248,15 +235,8 @@ void vcpu_restore_fpu_lazy(struct vcpu *
|
||
|
|
||
|
if ( cpu_has_xsave )
|
||
|
fpu_xrstor(v, XSTATE_LAZY);
|
||
|
- else if ( v->fpu_initialised )
|
||
|
- {
|
||
|
- if ( cpu_has_fxsr )
|
||
|
- fpu_fxrstor(v);
|
||
|
- else
|
||
|
- fpu_frstor(v);
|
||
|
- }
|
||
|
else
|
||
|
- fpu_init();
|
||
|
+ fpu_fxrstor(v);
|
||
|
|
||
|
v->fpu_initialised = 1;
|
||
|
v->fpu_dirtied = 1;
|
||
|
@@ -313,7 +293,14 @@ int vcpu_init_fpu(struct vcpu *v)
|
||
|
else
|
||
|
{
|
||
|
v->arch.fpu_ctxt = _xzalloc(sizeof(v->arch.xsave_area->fpu_sse), 16);
|
||
|
- if ( !v->arch.fpu_ctxt )
|
||
|
+ if ( v->arch.fpu_ctxt )
|
||
|
+ {
|
||
|
+ typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt;
|
||
|
+
|
||
|
+ fpu_sse->fcw = FCW_DEFAULT;
|
||
|
+ fpu_sse->mxcsr = MXCSR_DEFAULT;
|
||
|
+ }
|
||
|
+ else
|
||
|
rc = -ENOMEM;
|
||
|
}
|
||
|
|