diff options
-rw-r--r-- | xen/arch/x86/i387.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c index 6e22eba752..bba14ca978 100644 --- a/xen/arch/x86/i387.c +++ b/xen/arch/x86/i387.c @@ -59,10 +59,25 @@ static void xrstor(struct vcpu *v) "fildl %0" /* load to clear state */ : : "m" (ptr->fpu_sse) ); - asm volatile ( - ".byte " REX_PREFIX "0x0f,0xae,0x2f" - : - : "m" (*ptr), "a" (-1), "d" (-1), "D"(ptr) ); + /* + * XRSTOR can fault if passed a corrupted data block. We handle this + * possibility, which may occur if the block was passed to us by control + * tools or through VCPUOP_initialise, by silently clearing the block. + */ + asm volatile ( "1: .byte " REX_PREFIX "0x0f,0xae,0x2f\n" + ".section .fixup,\"ax\"\n" + "2: mov %4,%%ecx \n" + " xor %1,%1 \n" + " rep stosb \n" + " lea %3,%0 \n" + " dec %1 \n" + " jmp 1b \n" + ".previous \n" + _ASM_EXTABLE(1b, 2b) + : "+&D" (ptr) + : "a" (-1), "d" (-1), "m" (*ptr), + "m" (xsave_cntxt_size) + : "ecx" ); } static void load_mxcsr(unsigned long val) @@ -196,7 +211,7 @@ static void restore_fpu(struct vcpu *v) /* * FXRSTOR can fault if passed a corrupted data block. We handle this * possibility, which may occur if the block was passed to us by control - * tools, by silently clearing the block. + * tools or through VCPUOP_initialise, by silently clearing the block. */ if ( cpu_has_fxsr ) { |