Signed-off-by: Xu Dongxiao diff -r 59b8768d0d0d xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Wed Mar 05 11:18:25 2008 +0000 +++ b/xen/arch/x86/mm/shadow/multi.c Mon Mar 17 14:59:03 2008 +0800 @@ -3165,8 +3165,40 @@ static int sh_page_fault(struct vcpu *v, * the "second half" of a 64-bit pagetable write. */ for ( i = 0 ; i < 4 ; i++ ) { + unsigned long ins, rc; + uint8_t b; shadow_continue_emulation(&emul_ctxt, regs); v->arch.paging.last_write_was_pt = 0; + + rc = emul_ops->insn_fetch(x86_seg_cs, + regs->eip + sizeof(uint8_t), + &ins, sizeof(uint8_t), &emul_ctxt.ctxt); + if ( rc ) + break; + + b = (uint8_t)ins; + + /* If the instruction is IN/INS/OUT/OUTS */ + if ((b >= 0xe4 && b <= 0xe7) || (b >= 0xec && b <= 0xef) + || (b >= 0x6c && b <= 0x6f)) + break; + /* If the instruction is a REP prefix */ + else if (b == 0xf3) + { + rc = emul_ops->insn_fetch(x86_seg_cs, + regs->eip + 2*sizeof(uint8_t), + &ins, sizeof(uint8_t), &emul_ctxt.ctxt); + if ( rc ) + break; + + b = (uint8_t)ins; + + /* If the instruction after the REP prefix is IN/INS/OUT/OUTS */ + if ((b >= 0xe4 && b <= 0xe7) || (b >= 0xec && b <= 0xef) + || (b >= 0x6c && b <= 0x6f)) + break; + } + r = x86_emulate(&emul_ctxt.ctxt, emul_ops); if ( r == X86EMUL_OKAY ) { diff -r 59b8768d0d0d xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Wed Mar 05 11:18:25 2008 +0000 +++ b/xen/arch/x86/x86_emulate.c Mon Mar 17 14:59:03 2008 +0800 @@ -2255,7 +2255,6 @@ x86_emulate( case 0x6c ... 0x6d: /* ins %dx,%es:%edi */ { unsigned long nr_reps = get_rep_prefix(); - generate_exception_if(!mode_iopl(), EXC_GP, 0); dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; dst.mem.seg = x86_seg_es; dst.mem.off = truncate_ea(_regs.edi); @@ -2818,7 +2817,6 @@ x86_emulate( unsigned int port = ((b < 0xe8) ? insn_fetch_type(uint8_t) : (uint16_t)_regs.edx); - generate_exception_if(!mode_iopl(), EXC_GP, 0); op_bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; if ( b & 2 ) {