[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.0-testing] Change the x86_emulate() interface to pack all context arguments
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID d7f5c7ee728da6ace79be59e735d41b900a1452b # Parent 24ab638506197661d47f42116280d17ca006debb Change the x86_emulate() interface to pack all context arguments into a context structure. This context can then be handed to callback operations. Based on an original patch from Mats Petersson <mats.petersson@xxxxxxx> Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> xen-unstable changeset: 10159:41de9cd7971b565dd3286ce499a6b8063f6d686c xen-unstable date: Thu May 25 15:52:38 2006 +0100 Fix x86/64 build after previous changeset. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> xen-unstable changeset: 10161:f4f4dd936103d5478f88346f917ba68d5cd32e4f xen-unstable date: Thu May 25 16:00:09 2006 +0100 --- tools/tests/test_x86_emulator.c | 67 +++++++++++++++++++---------------- xen/arch/x86/mm.c | 31 ++++++++++------ xen/arch/x86/x86_emulate.c | 71 ++++++++++++++++++++------------------ xen/include/asm-x86/x86_emulate.h | 66 +++++++++++++++++++++-------------- 4 files changed, 135 insertions(+), 100 deletions(-) diff -r 24ab63850619 -r d7f5c7ee728d tools/tests/test_x86_emulator.c --- a/tools/tests/test_x86_emulator.c Mon Jun 05 17:20:48 2006 +0100 +++ b/tools/tests/test_x86_emulator.c Tue Jun 06 08:16:56 2006 +0100 @@ -17,7 +17,8 @@ static int read_any( static int read_any( unsigned long addr, unsigned long *val, - unsigned int bytes) + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { switch ( bytes ) { @@ -32,7 +33,8 @@ static int write_any( static int write_any( unsigned long addr, unsigned long val, - unsigned int bytes) + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { switch ( bytes ) { @@ -48,7 +50,8 @@ static int cmpxchg_any( unsigned long addr, unsigned long old, unsigned long new, - unsigned int bytes) + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { switch ( bytes ) { @@ -65,34 +68,38 @@ static int cmpxchg8b_any( unsigned long old_lo, unsigned long old_hi, unsigned long new_lo, - unsigned long new_hi) + unsigned long new_hi, + struct x86_emulate_ctxt *ctxt) { ((unsigned long *)addr)[0] = new_lo; ((unsigned long *)addr)[1] = new_hi; return X86EMUL_CONTINUE; } -static struct x86_mem_emulator emulops = { +static struct x86_emulate_ops emulops = { read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any }; int main(int argc, char **argv) { + struct x86_emulate_ctxt ctxt; struct cpu_user_regs regs; char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */ unsigned int res = 0x7FFFFFFF; u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 }; - unsigned long cr2; int rc; + + ctxt.regs = ®s; + ctxt.mode = X86EMUL_MODE_PROT32; printf("%-40s", "Testing addl %%ecx,(%%eax)..."); instr[0] = 0x01; instr[1] = 0x08; regs.eflags = 0x200; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - cr2 = (unsigned long)&res; + ctxt.cr2 = (unsigned long)&res; res = 0x7FFFFFFF; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x92345677) || (regs.eflags != 0xa94) || @@ -109,8 +116,8 @@ int main(int argc, char **argv) #else regs.ecx = 0x12345678UL; #endif - cr2 = (unsigned long)&res; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = (unsigned long)&res; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x92345677) || (regs.ecx != 0x8000000FUL) || @@ -124,8 +131,8 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.eax = 0x92345677UL; regs.ecx = 0xAA; - cr2 = (unsigned long)&res; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = (unsigned long)&res; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x923456AA) || (regs.eflags != 0x244) || @@ -140,8 +147,8 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.eax = 0xAABBCC77UL; regs.ecx = 0xFF; - cr2 = (unsigned long)&res; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = (unsigned long)&res; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x923456AA) || ((regs.eflags&0x240) != 0x200) || @@ -156,8 +163,8 @@ int main(int argc, char **argv) regs.eflags = 0x200; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - cr2 = (unsigned long)&res; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = (unsigned long)&res; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x12345678) || (regs.eflags != 0x200) || @@ -173,8 +180,8 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.eax = 0x923456AAUL; regs.ecx = 0xDDEEFF00L; - cr2 = (unsigned long)&res; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = (unsigned long)&res; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0xDDEEFF00) || (regs.eflags != 0x244) || @@ -192,8 +199,8 @@ int main(int argc, char **argv) regs.esi = (unsigned long)&res + 0; regs.edi = (unsigned long)&res + 2; regs.error_code = 0; /* read fault */ - cr2 = regs.esi; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = regs.esi; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x44554455) || (regs.eflags != 0x200) || @@ -210,8 +217,8 @@ int main(int argc, char **argv) regs.eflags = 0x200; regs.eip = (unsigned long)&instr[0]; regs.edi = (unsigned long)&res; - cr2 = regs.edi; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = regs.edi; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x2233445D) || ((regs.eflags&0x201) != 0x201) || @@ -228,8 +235,8 @@ int main(int argc, char **argv) regs.ecx = 0xCCCCFFFF; regs.eip = (unsigned long)&instr[0]; regs.edi = (unsigned long)cmpxchg8b_res; - cr2 = regs.edi; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = regs.edi; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (cmpxchg8b_res[0] != 0x9999AAAA) || (cmpxchg8b_res[1] != 0xCCCCFFFF) || @@ -242,8 +249,8 @@ int main(int argc, char **argv) instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f; regs.eip = (unsigned long)&instr[0]; regs.edi = (unsigned long)cmpxchg8b_res; - cr2 = regs.edi; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + ctxt.cr2 = regs.edi; + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (cmpxchg8b_res[0] != 0x9999AAAA) || (cmpxchg8b_res[1] != 0xCCCCFFFF) || @@ -258,9 +265,9 @@ int main(int argc, char **argv) instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - cr2 = (unsigned long)&res; + ctxt.cr2 = (unsigned long)&res; res = 0x82; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x82) || (regs.ecx != 0xFFFFFF82) || @@ -273,9 +280,9 @@ int main(int argc, char **argv) instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08; regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; - cr2 = (unsigned long)&res; + ctxt.cr2 = (unsigned long)&res; res = 0x1234aa82; - rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); + rc = x86_emulate_memop(&ctxt, &emulops); if ( (rc != 0) || (res != 0x1234aa82) || (regs.ecx != 0xaa82) || diff -r 24ab63850619 -r d7f5c7ee728d xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Mon Jun 05 17:20:48 2006 +0100 +++ b/xen/arch/x86/mm.c Tue Jun 06 08:16:56 2006 +0100 @@ -3176,15 +3176,16 @@ static int ptwr_emulated_update( /* Turn a sub-word access into a full-word access. */ if ( bytes != sizeof(paddr_t) ) { - int rc; - paddr_t full; - unsigned int offset = addr & (sizeof(paddr_t)-1); + paddr_t full; + unsigned int offset = addr & (sizeof(paddr_t)-1); /* Align address; read full word. */ addr &= ~(sizeof(paddr_t)-1); - if ( (rc = x86_emulate_read_std(addr, (unsigned long *)&full, - sizeof(paddr_t))) ) - return rc; + if ( copy_from_user(&full, (void *)addr, sizeof(paddr_t)) ) + { + propagate_page_fault(addr, 4); /* user mode, read fault */ + return X86EMUL_PROPAGATE_FAULT; + } /* Mask out bits provided by caller. */ full &= ~((((paddr_t)1 << (bytes*8)) - 1) << (offset*8)); /* Shift the caller value and OR in the missing bits. */ @@ -3262,7 +3263,8 @@ static int ptwr_emulated_write( static int ptwr_emulated_write( unsigned long addr, unsigned long val, - unsigned int bytes) + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { return ptwr_emulated_update(addr, 0, val, bytes, 0); } @@ -3271,7 +3273,8 @@ static int ptwr_emulated_cmpxchg( unsigned long addr, unsigned long old, unsigned long new, - unsigned int bytes) + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { return ptwr_emulated_update(addr, old, new, bytes, 1); } @@ -3281,7 +3284,8 @@ static int ptwr_emulated_cmpxchg8b( unsigned long old, unsigned long old_hi, unsigned long new, - unsigned long new_hi) + unsigned long new_hi, + struct x86_emulate_ctxt *ctxt) { if ( CONFIG_PAGING_LEVELS == 2 ) return X86EMUL_UNHANDLEABLE; @@ -3290,7 +3294,7 @@ static int ptwr_emulated_cmpxchg8b( addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1); } -static struct x86_mem_emulator ptwr_mem_emulator = { +static struct x86_emulate_ops ptwr_emulate_ops = { .read_std = x86_emulate_read_std, .write_std = x86_emulate_write_std, .read_emulated = x86_emulate_read_std, @@ -3309,6 +3313,7 @@ int ptwr_do_page_fault(struct domain *d, l2_pgentry_t *pl2e, l2e; int which, flags; unsigned long l2_idx; + struct x86_emulate_ctxt emul_ctxt; if ( unlikely(shadow_mode_enabled(d)) ) return 0; @@ -3463,8 +3468,10 @@ int ptwr_do_page_fault(struct domain *d, return EXCRET_fault_fixed; emulate: - if ( x86_emulate_memop(guest_cpu_user_regs(), addr, - &ptwr_mem_emulator, X86EMUL_MODE_HOST) ) + emul_ctxt.regs = guest_cpu_user_regs(); + emul_ctxt.cr2 = addr; + emul_ctxt.mode = X86EMUL_MODE_HOST; + if ( x86_emulate_memop(&emul_ctxt, &ptwr_emulate_ops) ) return 0; perfc_incrc(ptwr_emulations); return EXCRET_fault_fixed; diff -r 24ab63850619 -r d7f5c7ee728d xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Mon Jun 05 17:20:48 2006 +0100 +++ b/xen/arch/x86/x86_emulate.c Tue Jun 06 08:16:56 2006 +0100 @@ -363,12 +363,13 @@ do{ __asm__ __volatile__ ( #endif /* __i386__ */ /* Fetch next part of the instruction being emulated. */ -#define insn_fetch(_type, _size, _eip) \ -({ unsigned long _x; \ - if ( (rc = ops->read_std((unsigned long)(_eip), &_x, (_size))) != 0 ) \ - goto done; \ - (_eip) += (_size); \ - (_type)_x; \ +#define insn_fetch(_type, _size, _eip) \ +({ unsigned long _x; \ + rc = ops->read_std((unsigned long)(_eip), &_x, (_size), ctxt); \ + if ( rc != 0 ) \ + goto done; \ + (_eip) += (_size); \ + (_type)_x; \ }) /* Access/update address held in a register, based on addressing mode. */ @@ -427,12 +428,10 @@ decode_register( return p; } -int +int x86_emulate_memop( - struct cpu_user_regs *regs, - unsigned long cr2, - struct x86_mem_emulator *ops, - int mode) + struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) { uint8_t b, d, sib, twobyte = 0, rex_prefix = 0; uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; @@ -440,9 +439,11 @@ x86_emulate_memop( unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; int rc = 0; struct operand src, dst; + unsigned long cr2 = ctxt->cr2; + int mode = ctxt->mode; /* Shadow copy of register state. Committed on successful emulation. */ - struct cpu_user_regs _regs = *regs; + struct cpu_user_regs _regs = *ctxt->regs; switch ( mode ) { @@ -629,7 +630,7 @@ x86_emulate_memop( dst.bytes = (d & ByteOp) ? 1 : op_bytes; if ( !(d & Mov) && /* optimisation - avoid slow emulated read */ ((rc = ops->read_emulated((unsigned long)dst.ptr, - &dst.val, dst.bytes)) != 0) ) + &dst.val, dst.bytes, ctxt)) != 0) ) goto done; break; } @@ -671,7 +672,7 @@ x86_emulate_memop( src.type = OP_MEM; src.ptr = (unsigned long *)cr2; if ( (rc = ops->read_emulated((unsigned long)src.ptr, - &src.val, src.bytes)) != 0 ) + &src.val, src.bytes, ctxt)) != 0 ) goto done; src.orig_val = src.val; break; @@ -777,7 +778,7 @@ x86_emulate_memop( if ( mode == X86EMUL_MODE_PROT64 ) dst.bytes = 8; if ( (rc = ops->read_std(register_address(_regs.ss, _regs.esp), - &dst.val, dst.bytes)) != 0 ) + &dst.val, dst.bytes, ctxt)) != 0 ) goto done; register_address_increment(_regs.esp, dst.bytes); break; @@ -855,12 +856,12 @@ x86_emulate_memop( { dst.bytes = 8; if ( (rc = ops->read_std((unsigned long)dst.ptr, - &dst.val, 8)) != 0 ) + &dst.val, 8, ctxt)) != 0 ) goto done; } register_address_increment(_regs.esp, -dst.bytes); if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp), - dst.val, dst.bytes)) != 0 ) + dst.val, dst.bytes, ctxt)) != 0 ) goto done; dst.val = dst.orig_val; /* skanky: disable writeback */ break; @@ -888,10 +889,11 @@ x86_emulate_memop( case OP_MEM: if ( lock_prefix ) rc = ops->cmpxchg_emulated( - (unsigned long)dst.ptr, dst.orig_val, dst.val, dst.bytes); + (unsigned long)dst.ptr, dst.orig_val, + dst.val, dst.bytes, ctxt); else rc = ops->write_emulated( - (unsigned long)dst.ptr, dst.val, dst.bytes); + (unsigned long)dst.ptr, dst.val, dst.bytes, ctxt); if ( rc != 0 ) goto done; default: @@ -900,7 +902,7 @@ x86_emulate_memop( } /* Commit shadow register state. */ - *regs = _regs; + *ctxt->regs = _regs; done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; @@ -912,11 +914,11 @@ x86_emulate_memop( { if ( _regs.ecx == 0 ) { - regs->eip = _regs.eip; + ctxt->regs->eip = _regs.eip; goto done; } _regs.ecx--; - _regs.eip = regs->eip; + _regs.eip = ctxt->regs->eip; } switch ( b ) { @@ -929,14 +931,15 @@ x86_emulate_memop( dst.ptr = (unsigned long *)cr2; if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds, _regs.esi), - &dst.val, dst.bytes)) != 0 ) + &dst.val, dst.bytes, ctxt)) != 0 ) goto done; } else { /* Read fault: source is special memory. */ dst.ptr = (unsigned long *)register_address(_regs.es, _regs.edi); - if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 ) + if ( (rc = ops->read_emulated(cr2, &dst.val, + dst.bytes, ctxt)) != 0 ) goto done; } register_address_increment( @@ -959,7 +962,7 @@ x86_emulate_memop( dst.type = OP_REG; dst.bytes = (d & ByteOp) ? 1 : op_bytes; dst.ptr = (unsigned long *)&_regs.eax; - if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 ) + if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0 ) goto done; register_address_increment( _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); @@ -1075,8 +1078,8 @@ x86_emulate_memop( #if defined(__i386__) { unsigned long old_lo, old_hi; - if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4)) != 0) || - ((rc = ops->read_emulated(cr2+4, &old_hi, 4)) != 0) ) + if ( ((rc = ops->read_emulated(cr2+0, &old_lo, 4, ctxt)) != 0) || + ((rc = ops->read_emulated(cr2+4, &old_hi, 4, ctxt)) != 0) ) goto done; if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) ) { @@ -1091,8 +1094,8 @@ x86_emulate_memop( } else { - if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi, - _regs.ebx, _regs.ecx)) != 0 ) + if ( (rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi, _regs.ebx, + _regs.ecx, ctxt)) != 0 ) goto done; _regs.eflags |= EFLG_ZF; } @@ -1101,7 +1104,7 @@ x86_emulate_memop( #elif defined(__x86_64__) { unsigned long old, new; - if ( (rc = ops->read_emulated(cr2, &old, 8)) != 0 ) + if ( (rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0 ) goto done; if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) || ((uint32_t)(old>>32) != (uint32_t)_regs.edx) ) @@ -1113,7 +1116,7 @@ x86_emulate_memop( else { new = (_regs.ecx<<32)|(uint32_t)_regs.ebx; - if ( (rc = ops->cmpxchg_emulated(cr2, old, new, 8)) != 0 ) + if ( (rc = ops->cmpxchg_emulated(cr2, old, new, 8, ctxt)) != 0 ) goto done; _regs.eflags |= EFLG_ZF; } @@ -1137,7 +1140,8 @@ x86_emulate_read_std( x86_emulate_read_std( unsigned long addr, unsigned long *val, - unsigned int bytes) + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { *val = 0; if ( copy_from_user((void *)val, (void *)addr, bytes) ) @@ -1152,7 +1156,8 @@ x86_emulate_write_std( x86_emulate_write_std( unsigned long addr, unsigned long val, - unsigned int bytes) + unsigned int bytes, + struct x86_emulate_ctxt *ctxt) { if ( copy_to_user((void *)addr, (void *)&val, bytes) ) { diff -r 24ab63850619 -r d7f5c7ee728d xen/include/asm-x86/x86_emulate.h --- a/xen/include/asm-x86/x86_emulate.h Mon Jun 05 17:20:48 2006 +0100 +++ b/xen/include/asm-x86/x86_emulate.h Tue Jun 06 08:16:56 2006 +0100 @@ -9,8 +9,10 @@ #ifndef __X86_EMULATE_H__ #define __X86_EMULATE_H__ -/* - * x86_mem_emulator: +struct x86_emulate_ctxt; + +/* + * x86_emulate_ops: * * These operations represent the instruction emulator's interface to memory. * There are two categories of operation: those that act on ordinary memory @@ -47,7 +49,7 @@ #define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */ #define X86EMUL_RETRY_INSTR 2 /* retry the instruction for some reason */ #define X86EMUL_CMPXCHG_FAILED 2 /* cmpxchg did not see expected value */ -struct x86_mem_emulator +struct x86_emulate_ops { /* * read_std: Read bytes of standard (non-emulated/special) memory. @@ -59,7 +61,8 @@ struct x86_mem_emulator int (*read_std)( unsigned long addr, unsigned long *val, - unsigned int bytes); + unsigned int bytes, + struct x86_emulate_ctxt *ctxt); /* * write_std: Write bytes of standard (non-emulated/special) memory. @@ -71,7 +74,8 @@ struct x86_mem_emulator int (*write_std)( unsigned long addr, unsigned long val, - unsigned int bytes); + unsigned int bytes, + struct x86_emulate_ctxt *ctxt); /* * read_emulated: Read bytes from emulated/special memory area. @@ -82,7 +86,8 @@ struct x86_mem_emulator int (*read_emulated)( unsigned long addr, unsigned long *val, - unsigned int bytes); + unsigned int bytes, + struct x86_emulate_ctxt *ctxt); /* * write_emulated: Read bytes from emulated/special memory area. @@ -93,7 +98,8 @@ struct x86_mem_emulator int (*write_emulated)( unsigned long addr, unsigned long val, - unsigned int bytes); + unsigned int bytes, + struct x86_emulate_ctxt *ctxt); /* * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an @@ -107,11 +113,12 @@ struct x86_mem_emulator unsigned long addr, unsigned long old, unsigned long new, - unsigned int bytes); - - /* - * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an - * emulated/special memory area. + unsigned int bytes, + struct x86_emulate_ctxt *ctxt); + + /* + * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an + * emulated/special memory area. * @addr: [IN ] Linear address to access. * @old: [IN ] Value expected to be current at @addr. * @new: [IN ] Value to write to @addr. @@ -126,7 +133,8 @@ struct x86_mem_emulator unsigned long old_lo, unsigned long old_hi, unsigned long new_lo, - unsigned long new_hi); + unsigned long new_hi, + struct x86_emulate_ctxt *ctxt); }; /* Standard reader/writer functions that callers may wish to use. */ @@ -134,14 +142,28 @@ x86_emulate_read_std( x86_emulate_read_std( unsigned long addr, unsigned long *val, - unsigned int bytes); + unsigned int bytes, + struct x86_emulate_ctxt *ctxt); extern int x86_emulate_write_std( unsigned long addr, unsigned long val, - unsigned int bytes); + unsigned int bytes, + struct x86_emulate_ctxt *ctxt); struct cpu_user_regs; + +struct x86_emulate_ctxt +{ + /* Register state before/after emulation. */ + struct cpu_user_regs *regs; + + /* Linear faulting address (if emulating a page-faulting instruction). */ + unsigned long cr2; + + /* Emulated execution mode, represented by an X86EMUL_MODE value. */ + int mode; +}; /* Execution mode, passed to the emulator. */ #define X86EMUL_MODE_REAL 0 /* Real mode. */ @@ -159,25 +181,19 @@ struct cpu_user_regs; /* * x86_emulate_memop: Emulate an instruction that faulted attempting to * read/write a 'special' memory area. - * @regs: Register state at time of fault. - * @cr2: Linear faulting address within an emulated/special memory area. - * @ops: Interface to access special memory. - * @mode: Emulated execution mode, represented by an X86EMUL_MODE value. * Returns -1 on failure, 0 on success. */ -extern int +int x86_emulate_memop( - struct cpu_user_regs *regs, - unsigned long cr2, - struct x86_mem_emulator *ops, - int mode); + struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops); /* * Given the 'reg' portion of a ModRM byte, and a register block, return a * pointer into the block that addresses the relevant register. * @highbyte_regs specifies whether to decode AH,CH,DH,BH. */ -extern void * +void * decode_register( uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |