aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-03-18 09:20:22 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:16:23 -0400
commitd9271123a46011af26da680baeb7fdf67b498abf (patch)
treea63c0e86cb1e2d0203b84f3d3ce677d436668ce1 /arch
parenta682e35449abc83d260a8219015c7cb4b25ecced (diff)
KVM: x86 emulator: during rep emulation decrement ECX only if emulation succeeded
Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 3b32270a20db..594574d8b9e9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2411,13 +2411,13 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
2411} 2411}
2412 2412
2413static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base, 2413static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned long base,
2414 int reg, unsigned long **ptr) 2414 int reg, struct operand *op)
2415{ 2415{
2416 struct decode_cache *c = &ctxt->decode; 2416 struct decode_cache *c = &ctxt->decode;
2417 int df = (ctxt->eflags & EFLG_DF) ? -1 : 1; 2417 int df = (ctxt->eflags & EFLG_DF) ? -1 : 1;
2418 2418
2419 register_address_increment(c, &c->regs[reg], df * c->src.bytes); 2419 register_address_increment(c, &c->regs[reg], df * op->bytes);
2420 *ptr = (unsigned long *)register_address(c, base, c->regs[reg]); 2420 op->ptr = (unsigned long *)register_address(c, base, c->regs[reg]);
2421} 2421}
2422 2422
2423int 2423int
@@ -2483,7 +2483,6 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
2483 goto done; 2483 goto done;
2484 } 2484 }
2485 } 2485 }
2486 register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
2487 c->eip = ctxt->eip; 2486 c->eip = ctxt->eip;
2488 } 2487 }
2489 2488
@@ -2936,11 +2935,13 @@ writeback:
2936 2935
2937 if ((c->d & SrcMask) == SrcSI) 2936 if ((c->d & SrcMask) == SrcSI)
2938 string_addr_inc(ctxt, seg_override_base(ctxt, c), VCPU_REGS_RSI, 2937 string_addr_inc(ctxt, seg_override_base(ctxt, c), VCPU_REGS_RSI,
2939 &c->src.ptr); 2938 &c->src);
2940 2939
2941 if ((c->d & DstMask) == DstDI) 2940 if ((c->d & DstMask) == DstDI)
2942 string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, 2941 string_addr_inc(ctxt, es_base(ctxt), VCPU_REGS_RDI, &c->dst);
2943 &c->dst.ptr); 2942
2943 if (c->rep_prefix && (c->d & String))
2944 register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
2944 2945
2945 /* Commit shadow register state. */ 2946 /* Commit shadow register state. */
2946 memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); 2947 memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);