[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86_emulate: Do not request emulation of REP instructions beyond the
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1219157791 -3600 # Node ID 6e3c97f43f9c79506c834fe0661b4ceb7ba21a99 # Parent 7c10be016e432163c8d95a9d5a79636ff6133e93 x86_emulate: Do not request emulation of REP instructions beyond the point at which the index register (SI/DI) wraps. This can cause a discontinuity in the address range accessed by the repeated instruction. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/x86_emulate/x86_emulate.c | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-) diff -r 7c10be016e43 -r 6e3c97f43f9c xen/arch/x86/x86_emulate/x86_emulate.c --- a/xen/arch/x86/x86_emulate/x86_emulate.c Tue Aug 19 10:51:41 2008 +0100 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c Tue Aug 19 15:56:31 2008 +0100 @@ -681,6 +681,15 @@ static void __put_rep_prefix( __put_rep_prefix(&_regs, ctxt->regs, ad_bytes, reps_completed); \ }) +/* Clip maximum repetitions so that the index register only just wraps. */ +#define truncate_ea_and_reps(ea, reps, bytes_per_rep) ({ \ + unsigned long __todo = (ctxt->regs->eflags & EF_DF) ? (ea) : ~(ea); \ + __todo = truncate_word(__todo, ad_bytes); \ + __todo = (__todo / (bytes_per_rep)) + 1; \ + (reps) = (__todo < (reps)) ? __todo : (reps); \ + truncate_word((ea), ad_bytes); \ +}) + /* Compatibility function: read guest memory, zero-extend result to a ulong. */ static int read_ulong( enum x86_segment seg, @@ -2385,7 +2394,7 @@ x86_emulate( unsigned int port = (uint16_t)_regs.edx; dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; dst.mem.seg = x86_seg_es; - dst.mem.off = truncate_ea(_regs.edi); + dst.mem.off = truncate_ea_and_reps(_regs.edi, nr_reps, dst.bytes); if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops)) != 0 ) goto done; if ( (nr_reps > 1) && (ops->rep_ins != NULL) && @@ -2414,11 +2423,11 @@ x86_emulate( unsigned long nr_reps = get_rep_prefix(); unsigned int port = (uint16_t)_regs.edx; dst.bytes = !(b & 1) ? 1 : (op_bytes == 8) ? 4 : op_bytes; + ea.mem.off = truncate_ea_and_reps(_regs.esi, nr_reps, dst.bytes); if ( (rc = ioport_access_check(port, dst.bytes, ctxt, ops)) != 0 ) goto done; if ( (nr_reps > 1) && (ops->rep_outs != NULL) && - ((rc = ops->rep_outs(ea.mem.seg, truncate_ea(_regs.esi), - port, dst.bytes, + ((rc = ops->rep_outs(ea.mem.seg, ea.mem.off, port, dst.bytes, &nr_reps, ctxt)) != X86EMUL_UNHANDLEABLE) ) { if ( rc != 0 ) @@ -2569,7 +2578,7 @@ x86_emulate( unsigned long nr_reps = get_rep_prefix(); dst.bytes = (d & ByteOp) ? 1 : op_bytes; dst.mem.seg = x86_seg_es; - dst.mem.off = truncate_ea(_regs.edi); + dst.mem.off = truncate_ea_and_reps(_regs.edi, nr_reps, dst.bytes); if ( (nr_reps > 1) && (ops->rep_movs != NULL) && ((rc = ops->rep_movs(ea.mem.seg, truncate_ea(_regs.esi), dst.mem.seg, dst.mem.off, dst.bytes, _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |