aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/i387.c
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-04-28 18:26:25 +0000
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-04-28 18:26:25 +0000
commit0dfa4d0545c213840bced14daf700496ae31d308 (patch)
tree162454479435747bb75fa230f7af57b37232a284 /xen/arch/x86/i387.c
parent3ba18b6857ce0e98e761a70feb4602ea743f9ed5 (diff)
downloadxen-0dfa4d0545c213840bced14daf700496ae31d308.tar.gz
xen-0dfa4d0545c213840bced14daf700496ae31d308.tar.bz2
xen-0dfa4d0545c213840bced14daf700496ae31d308.zip
bitkeeper revision 1.1389.1.5 (42712ad1Qoo2MSKU_8_-kkJWHY9E9g)
Handle the possibility that FXRSTOR may fault by silently clearing the data area that it is restoring from. This may occur if control tools reload a saved VM image without adequate checking, for example. Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'xen/arch/x86/i387.c')
-rw-r--r--xen/arch/x86/i387.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
index f25973398f..08dc9fdcb7 100644
--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -46,10 +46,34 @@ void save_init_fpu(struct exec_domain *tsk)
void restore_fpu(struct exec_domain *tsk)
{
+ /*
+ * 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.
+ */
if ( cpu_has_fxsr )
__asm__ __volatile__ (
- "fxrstor %0"
- : : "m" (tsk->arch.guest_context.fpu_ctxt) );
+ "1: fxrstor %0 \n"
+ ".section .fixup,\"ax\" \n"
+ "2: push %%"__OP"ax \n"
+ " push %%"__OP"cx \n"
+ " push %%"__OP"di \n"
+ " lea %0,%%"__OP"di \n"
+ " mov %1,%%ecx \n"
+ " xor %%eax,%%eax \n"
+ " rep ; stosl \n"
+ " pop %%"__OP"di \n"
+ " pop %%"__OP"cx \n"
+ " pop %%"__OP"ax \n"
+ " jmp 1b \n"
+ ".previous \n"
+ ".section __ex_table,\"a\"\n"
+ " "__FIXUP_ALIGN" \n"
+ " "__FIXUP_WORD" 1b,2b \n"
+ ".previous \n"
+ :
+ : "m" (tsk->arch.guest_context.fpu_ctxt),
+ "i" (sizeof(tsk->arch.guest_context.fpu_ctxt)/4) );
else
__asm__ __volatile__ (
"frstor %0"