aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-08-25 05:47:42 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:51:33 -0400
commit3e2f65d57a0c1897fcc3287eeb41f117f4d021e5 (patch)
tree10feb7c8eef270a8f6767cf20340dc78b2e118e3 /arch
parent6e2fb2cadd9a523ff5494d4c4d53c0d3e0024691 (diff)
KVM: x86 emulator: move string instruction completion check into separate function
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.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 42d42ca2c37b..3dcbc1d0a59d 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2933,6 +2933,28 @@ done:
2933 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; 2933 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
2934} 2934}
2935 2935
2936static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
2937{
2938 struct decode_cache *c = &ctxt->decode;
2939
2940 /* The second termination condition only applies for REPE
2941 * and REPNE. Test if the repeat string operation prefix is
2942 * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
2943 * corresponding termination condition according to:
2944 * - if REPE/REPZ and ZF = 0 then done
2945 * - if REPNE/REPNZ and ZF = 1 then done
2946 */
2947 if (((c->b == 0xa6) || (c->b == 0xa7) ||
2948 (c->b == 0xae) || (c->b == 0xaf))
2949 && (((c->rep_prefix == REPE_PREFIX) &&
2950 ((ctxt->eflags & EFLG_ZF) == 0))
2951 || ((c->rep_prefix == REPNE_PREFIX) &&
2952 ((ctxt->eflags & EFLG_ZF) == EFLG_ZF))))
2953 return true;
2954
2955 return false;
2956}
2957
2936int 2958int
2937x86_emulate_insn(struct x86_emulate_ctxt *ctxt) 2959x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
2938{ 2960{
@@ -3423,19 +3445,8 @@ writeback:
3423 if (c->rep_prefix && (c->d & String)) { 3445 if (c->rep_prefix && (c->d & String)) {
3424 struct read_cache *r = &ctxt->decode.io_read; 3446 struct read_cache *r = &ctxt->decode.io_read;
3425 register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); 3447 register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
3426 /* The second termination condition only applies for REPE 3448
3427 * and REPNE. Test if the repeat string operation prefix is 3449 if (string_insn_completed(ctxt))
3428 * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
3429 * corresponding termination condition according to:
3430 * - if REPE/REPZ and ZF = 0 then done
3431 * - if REPNE/REPNZ and ZF = 1 then done
3432 */
3433 if (((c->b == 0xa6) || (c->b == 0xa7) ||
3434 (c->b == 0xae) || (c->b == 0xaf))
3435 && (((c->rep_prefix == REPE_PREFIX) &&
3436 ((ctxt->eflags & EFLG_ZF) == 0))
3437 || ((c->rep_prefix == REPNE_PREFIX) &&
3438 ((ctxt->eflags & EFLG_ZF) == EFLG_ZF))))
3439 ctxt->restart = false; 3450 ctxt->restart = false;
3440 /* 3451 /*
3441 * Re-enter guest when pio read ahead buffer is empty or, 3452 * Re-enter guest when pio read ahead buffer is empty or,