diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-08-25 05:47:43 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:34 -0400 |
commit | d2ddd1c48364e4161052d6089f06b2cf3c50496b (patch) | |
tree | f8dd6a949e5006e2f39575b567f22d9033b9d1a7 /arch/x86/kvm/emulate.c | |
parent | 3e2f65d57a0c1897fcc3287eeb41f117f4d021e5 (diff) |
KVM: x86 emulator: get rid of "restart" in emulation context.
x86_emulate_insn() will return 1 if instruction can be restarted
without re-entering a guest.
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 | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 3dcbc1d0a59d..ec35a71d8b5d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -437,7 +437,6 @@ static void emulate_exception(struct x86_emulate_ctxt *ctxt, int vec, | |||
437 | ctxt->exception = vec; | 437 | ctxt->exception = vec; |
438 | ctxt->error_code = error; | 438 | ctxt->error_code = error; |
439 | ctxt->error_code_valid = valid; | 439 | ctxt->error_code_valid = valid; |
440 | ctxt->restart = false; | ||
441 | } | 440 | } |
442 | 441 | ||
443 | static void emulate_gp(struct x86_emulate_ctxt *ctxt, int err) | 442 | static void emulate_gp(struct x86_emulate_ctxt *ctxt, int err) |
@@ -2633,9 +2632,6 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt) | |||
2633 | struct opcode opcode, *g_mod012, *g_mod3; | 2632 | struct opcode opcode, *g_mod012, *g_mod3; |
2634 | struct operand memop = { .type = OP_NONE }; | 2633 | struct operand memop = { .type = OP_NONE }; |
2635 | 2634 | ||
2636 | /* we cannot decode insn before we complete previous rep insn */ | ||
2637 | WARN_ON(ctxt->restart); | ||
2638 | |||
2639 | c->eip = ctxt->eip; | 2635 | c->eip = ctxt->eip; |
2640 | c->fetch.start = c->fetch.end = c->eip; | 2636 | c->fetch.start = c->fetch.end = c->eip; |
2641 | ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS); | 2637 | ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS); |
@@ -2985,10 +2981,8 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
2985 | } | 2981 | } |
2986 | 2982 | ||
2987 | if (c->rep_prefix && (c->d & String)) { | 2983 | if (c->rep_prefix && (c->d & String)) { |
2988 | ctxt->restart = true; | ||
2989 | /* All REP prefixes have the same first termination condition */ | 2984 | /* All REP prefixes have the same first termination condition */ |
2990 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { | 2985 | if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) { |
2991 | ctxt->restart = false; | ||
2992 | ctxt->eip = c->eip; | 2986 | ctxt->eip = c->eip; |
2993 | goto done; | 2987 | goto done; |
2994 | } | 2988 | } |
@@ -3446,28 +3440,29 @@ writeback: | |||
3446 | struct read_cache *r = &ctxt->decode.io_read; | 3440 | struct read_cache *r = &ctxt->decode.io_read; |
3447 | register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); | 3441 | register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1); |
3448 | 3442 | ||
3449 | if (string_insn_completed(ctxt)) | 3443 | if (!string_insn_completed(ctxt)) { |
3450 | ctxt->restart = false; | 3444 | /* |
3451 | /* | 3445 | * Re-enter guest when pio read ahead buffer is empty |
3452 | * Re-enter guest when pio read ahead buffer is empty or, | 3446 | * or, if it is not used, after each 1024 iteration. |
3453 | * if it is not used, after each 1024 iteration. | 3447 | */ |
3454 | */ | 3448 | if ((r->end != 0 || c->regs[VCPU_REGS_RCX] & 0x3ff) && |
3455 | else if ((r->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) || | 3449 | (r->end == 0 || r->end != r->pos)) { |
3456 | (r->end != 0 && r->end == r->pos)) { | 3450 | /* |
3457 | ctxt->restart = false; | 3451 | * Reset read cache. Usually happens before |
3458 | c->eip = ctxt->eip; | 3452 | * decode, but since instruction is restarted |
3453 | * we have to do it here. | ||
3454 | */ | ||
3455 | ctxt->decode.mem_read.end = 0; | ||
3456 | return EMULATION_RESTART; | ||
3457 | } | ||
3458 | goto done; /* skip rip writeback */ | ||
3459 | } | 3459 | } |
3460 | } | 3460 | } |
3461 | /* | 3461 | |
3462 | * reset read cache here in case string instruction is restared | 3462 | ctxt->eip = c->eip; |
3463 | * without decoding | ||
3464 | */ | ||
3465 | ctxt->decode.mem_read.end = 0; | ||
3466 | if (!ctxt->restart) | ||
3467 | ctxt->eip = c->eip; | ||
3468 | 3463 | ||
3469 | done: | 3464 | done: |
3470 | return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; | 3465 | return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK; |
3471 | 3466 | ||
3472 | twobyte_insn: | 3467 | twobyte_insn: |
3473 | switch (c->b) { | 3468 | switch (c->b) { |