[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Clean up EA computation in emulator.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxxx # Node ID e4bb22422b50871e26120d39b5667c9091d49f62 # Parent d37b210bb8a7fc3154c72adb6b673f47d57864c4 [XEN] Clean up EA computation in emulator. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/x86_emulate.c | 41 +++++++++++++++++++++-------------------- 1 files changed, 21 insertions(+), 20 deletions(-) diff -r d37b210bb8a7 -r e4bb22422b50 xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Sun Nov 26 13:37:27 2006 +0000 +++ b/xen/arch/x86/x86_emulate.c Sun Nov 26 13:52:48 2006 +0000 @@ -379,9 +379,11 @@ do{ __asm__ __volatile__ ( /* Access/update address held in a register, based on addressing mode. */ #define register_address(sel, reg) \ +({ unsigned long __reg = (reg); \ (((mode == X86EMUL_MODE_REAL) ? ((unsigned long)(sel) << 4) : 0) + \ - ((ad_bytes == sizeof(unsigned long)) ? (reg) : \ - ((reg) & ((1UL << (ad_bytes << 3)) - 1)))) + ((ad_bytes == sizeof(unsigned long)) ? __reg : \ + (__reg & ((1UL << (ad_bytes << 3)) - 1)))); \ +}) #define register_address_increment(reg, inc) \ do { \ int _inc = (inc); /* signed type ensures sign extension to long */ \ @@ -399,7 +401,7 @@ do { * effective address it is okay for us to fail the emulation. */ #define page_boundary_test() do { \ - if ( ((cr2 & (PAGE_SIZE-1)) == 0) && ((ea & 3) != 0) ) \ + if ( ((cr2 & (PAGE_SIZE-1)) == 0) && ((ea & 7) != 0) ) \ goto bad_ea; \ } while ( 0 ) @@ -448,17 +450,17 @@ x86_emulate_memop( struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { + /* Shadow copy of register state. Committed on successful emulation. */ + struct cpu_user_regs _regs = *ctxt->regs; + uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0; uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; - uint16_t *seg = NULL; /* override segment */ + uint16_t *seg = &_regs.ds; /* override segment */ unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; int rc = 0; struct operand src, dst; unsigned long ea = 0, cr2 = ctxt->cr2; int mode = ctxt->mode; - - /* Shadow copy of register state. Committed on successful emulation. */ - struct cpu_user_regs _regs = *ctxt->regs; /* * We do not emulate faults on instruction fetch. We assume that the @@ -592,7 +594,6 @@ x86_emulate_memop( case 1: ea += insn_fetch(uint8_t); break; case 2: ea += insn_fetch(uint16_t); break; } - ea = (uint16_t)ea; } else { @@ -638,10 +639,9 @@ x86_emulate_memop( case 1: ea += insn_fetch(uint8_t); break; case 2: ea += insn_fetch(uint32_t); break; } - if ( ad_bytes == 4 ) - ea = (uint32_t)ea; - } - + } + + ea = register_address(*seg, ea); page_boundary_test(); } @@ -809,12 +809,14 @@ x86_emulate_memop( case 0xa0 ... 0xa1: /* mov */ dst.ptr = (unsigned long *)&_regs.eax; dst.val = src.val; - ea = _insn_fetch(ad_bytes); /* src effective address */ + /* Source EA is not encoded via ModRM. */ + ea = register_address(*seg, _insn_fetch(ad_bytes)); page_boundary_test(); break; case 0xa2 ... 0xa3: /* mov */ dst.val = (unsigned long)_regs.eax; - ea = _insn_fetch(ad_bytes); /* dst effective address */ + /* Destination EA is not encoded via ModRM. */ + ea = register_address(*seg, _insn_fetch(ad_bytes)); page_boundary_test(); break; case 0x88 ... 0x8b: /* mov */ @@ -991,11 +993,10 @@ x86_emulate_memop( { /* Write fault: destination is special memory. */ dst.ptr = (unsigned long *)cr2; - if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds, - _regs.esi), + if ( (rc = ops->read_std(register_address(*seg, _regs.esi), &dst.val, dst.bytes, ctxt)) != 0 ) goto done; - ea = _regs.edi & ((1UL << (ad_bytes*8)) - 1UL); + ea = register_address(_regs.es, _regs.edi); } else { @@ -1004,7 +1005,7 @@ x86_emulate_memop( if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes, ctxt)) != 0 ) goto done; - ea = _regs.esi & ((1UL << (ad_bytes*8)) - 1UL); + ea = register_address(*seg, _regs.esi); } register_address_increment( _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); @@ -1019,7 +1020,7 @@ x86_emulate_memop( dst.val = _regs.eax; register_address_increment( _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); - ea = _regs.edi & ((1UL << (ad_bytes*8)) - 1UL); + ea = register_address(_regs.es, _regs.edi); page_boundary_test(); break; case 0xac ... 0xad: /* lods */ @@ -1030,7 +1031,7 @@ x86_emulate_memop( goto done; register_address_increment( _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); - ea = _regs.esi & ((1UL << (ad_bytes*8)) - 1UL); + ea = register_address(*seg, _regs.esi); page_boundary_test(); break; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |