ia64/xen-unstable
changeset 16860:5f3a178a80fc
x86_emulate: Emulate FNINIT, FNSTCW, FNSTSW x87 instructions.
Provide new hook ->load_fpu_ctxt() to ensure emulated environment's
FPU state is loaded onto the local processor.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Provide new hook ->load_fpu_ctxt() to ensure emulated environment's
FPU state is loaded onto the local processor.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Wed Jan 23 14:30:29 2008 +0000 (2008-01-23) |
parents | 7f940c605893 |
children | 5a3448506d9c |
files | xen/arch/x86/x86_emulate.c xen/include/asm-x86/x86_emulate.h |
line diff
1.1 --- a/xen/arch/x86/x86_emulate.c Wed Jan 23 13:59:24 2008 +0000 1.2 +++ b/xen/arch/x86/x86_emulate.c Wed Jan 23 14:30:29 2008 +0000 1.3 @@ -159,7 +159,7 @@ static uint8_t opcode_table[256] = { 1.4 ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 1.5 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 1.6 /* 0xD8 - 0xDF */ 1.7 - 0, 0, 0, 0, 0, 0, 0, 0, 1.8 + 0, ImplicitOps|ModRM, 0, ImplicitOps|ModRM, 0, ImplicitOps|ModRM, 0, 0, 1.9 /* 0xE0 - 0xE7 */ 1.10 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 1.11 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 1.12 @@ -864,7 +864,7 @@ x86_emulate( 1.13 struct cpu_user_regs _regs = *ctxt->regs; 1.14 1.15 uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0; 1.16 - uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; 1.17 + uint8_t modrm = 0, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; 1.18 unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes; 1.19 #define REPE_PREFIX 1 1.20 #define REPNE_PREFIX 2 1.21 @@ -2517,6 +2517,36 @@ x86_emulate( 1.22 break; 1.23 } 1.24 1.25 + case 0xd9: /* FPU 0xd9 */ 1.26 + fail_if(ops->load_fpu_ctxt == NULL); 1.27 + ops->load_fpu_ctxt(ctxt); 1.28 + fail_if((modrm_reg & 7) != 7); 1.29 + fail_if(modrm_reg >= 0xc0); 1.30 + /* fnstcw m2byte */ 1.31 + ea.bytes = 2; 1.32 + dst = ea; 1.33 + asm volatile ( "fnstcw %0" : "=m" (dst.val) ); 1.34 + break; 1.35 + 1.36 + case 0xdb: /* FPU 0xdb */ 1.37 + fail_if(ops->load_fpu_ctxt == NULL); 1.38 + ops->load_fpu_ctxt(ctxt); 1.39 + fail_if(modrm != 0xe3); 1.40 + /* fninit */ 1.41 + asm volatile ( "fninit" ); 1.42 + break; 1.43 + 1.44 + case 0xdd: /* FPU 0xdd */ 1.45 + fail_if(ops->load_fpu_ctxt == NULL); 1.46 + ops->load_fpu_ctxt(ctxt); 1.47 + fail_if((modrm_reg & 7) != 7); 1.48 + fail_if(modrm_reg >= 0xc0); 1.49 + /* fnstsw m2byte */ 1.50 + ea.bytes = 2; 1.51 + dst = ea; 1.52 + asm volatile ( "fnstsw %0" : "=m" (dst.val) ); 1.53 + break; 1.54 + 1.55 case 0xe0 ... 0xe2: /* loop{,z,nz} */ { 1.56 int rel = insn_fetch_type(int8_t); 1.57 int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */
2.1 --- a/xen/include/asm-x86/x86_emulate.h Wed Jan 23 13:59:24 2008 +0000 2.2 +++ b/xen/include/asm-x86/x86_emulate.h Wed Jan 23 14:30:29 2008 +0000 2.3 @@ -340,6 +340,10 @@ struct x86_emulate_ops 2.4 uint8_t vector, 2.5 uint8_t insn_len, 2.6 struct x86_emulate_ctxt *ctxt); 2.7 + 2.8 + /* load_fpu_ctxt: Load emulated environment's FPU state onto processor. */ 2.9 + void (*load_fpu_ctxt)( 2.10 + struct x86_emulate_ctxt *ctxt); 2.11 }; 2.12 2.13 struct cpu_user_regs;