diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-08-25 05:47:42 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:33 -0400 |
commit | 3e2f65d57a0c1897fcc3287eeb41f117f4d021e5 (patch) | |
tree | 10feb7c8eef270a8f6767cf20340dc78b2e118e3 /arch/x86/kvm/emulate.c | |
parent | 6e2fb2cadd9a523ff5494d4c4d53c0d3e0024691 (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/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 37 |
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 | ||
2936 | static 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 | |||
2936 | int | 2958 | int |
2937 | x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | 2959 | x86_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, |