* [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable.
@ 2010-08-25 9:47 Gleb Natapov
2010-08-25 9:47 ` [PATCHv2 2/3] KVM: x86 emulator: move string instruction completion check into separate function Gleb Natapov
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Gleb Natapov @ 2010-08-25 9:47 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
arch/x86/kvm/emulate.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 4a89348..8a77c99 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3424,7 +3424,7 @@ writeback:
&c->dst);
if (c->rep_prefix && (c->d & String)) {
- struct read_cache *rc = &ctxt->decode.io_read;
+ struct read_cache *r = &ctxt->decode.io_read;
register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
/* The second termination condition only applies for REPE
* and REPNE. Test if the repeat string operation prefix is
@@ -3444,8 +3444,8 @@ writeback:
* Re-enter guest when pio read ahead buffer is empty or,
* if it is not used, after each 1024 iteration.
*/
- else if ((rc->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) ||
- (rc->end != 0 && rc->end == rc->pos)) {
+ else if ((r->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) ||
+ (r->end != 0 && r->end == r->pos)) {
ctxt->restart = false;
c->eip = ctxt->eip;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv2 2/3] KVM: x86 emulator: move string instruction completion check into separate function
2010-08-25 9:47 [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable Gleb Natapov
@ 2010-08-25 9:47 ` Gleb Natapov
2010-08-25 9:47 ` [PATCHv2 3/3] KVM: x86 emulator: get rid of "restart" in emulation context Gleb Natapov
2010-08-26 15:23 ` [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable Marcelo Tosatti
2 siblings, 0 replies; 5+ messages in thread
From: Gleb Natapov @ 2010-08-25 9:47 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
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 8a77c99..922f874 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2938,6 +2938,28 @@ done:
return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
}
+static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
+{
+ struct decode_cache *c = &ctxt->decode;
+
+ /* The second termination condition only applies for REPE
+ * and REPNE. Test if the repeat string operation prefix is
+ * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
+ * corresponding termination condition according to:
+ * - if REPE/REPZ and ZF = 0 then done
+ * - if REPNE/REPNZ and ZF = 1 then done
+ */
+ if (((c->b == 0xa6) || (c->b == 0xa7) ||
+ (c->b == 0xae) || (c->b == 0xaf))
+ && (((c->rep_prefix == REPE_PREFIX) &&
+ ((ctxt->eflags & EFLG_ZF) == 0))
+ || ((c->rep_prefix == REPNE_PREFIX) &&
+ ((ctxt->eflags & EFLG_ZF) == EFLG_ZF))))
+ return true;
+
+ return false;
+}
+
int
x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
{
@@ -3426,19 +3448,8 @@ writeback:
if (c->rep_prefix && (c->d & String)) {
struct read_cache *r = &ctxt->decode.io_read;
register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
- /* The second termination condition only applies for REPE
- * and REPNE. Test if the repeat string operation prefix is
- * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
- * corresponding termination condition according to:
- * - if REPE/REPZ and ZF = 0 then done
- * - if REPNE/REPNZ and ZF = 1 then done
- */
- if (((c->b == 0xa6) || (c->b == 0xa7) ||
- (c->b == 0xae) || (c->b == 0xaf))
- && (((c->rep_prefix == REPE_PREFIX) &&
- ((ctxt->eflags & EFLG_ZF) == 0))
- || ((c->rep_prefix == REPNE_PREFIX) &&
- ((ctxt->eflags & EFLG_ZF) == EFLG_ZF))))
+
+ if (string_insn_completed(ctxt))
ctxt->restart = false;
/*
* Re-enter guest when pio read ahead buffer is empty or,
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCHv2 3/3] KVM: x86 emulator: get rid of "restart" in emulation context.
2010-08-25 9:47 [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable Gleb Natapov
2010-08-25 9:47 ` [PATCHv2 2/3] KVM: x86 emulator: move string instruction completion check into separate function Gleb Natapov
@ 2010-08-25 9:47 ` Gleb Natapov
2010-08-25 10:36 ` Avi Kivity
2010-08-26 15:23 ` [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable Marcelo Tosatti
2 siblings, 1 reply; 5+ messages in thread
From: Gleb Natapov @ 2010-08-25 9:47 UTC (permalink / raw)
To: avi, mtosatti; +Cc: kvm
x86_emulate_insn() will return 1 if instruction can be restarted
without re-entering a guest.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
arch/x86/include/asm/kvm_emulate.h | 4 ++-
arch/x86/kvm/emulate.c | 43 ++++++++++++++++--------------------
arch/x86/kvm/x86.c | 16 ++++++------
3 files changed, 30 insertions(+), 33 deletions(-)
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index f22e5da..3a82ecd 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -220,7 +220,6 @@ struct x86_emulate_ctxt {
/* interruptibility state, as a result of execution of STI or MOV SS */
int interruptibility;
- bool restart; /* restart string instruction after writeback */
bool perm_ok; /* do not check permissions if true */
int exception; /* exception that happens during emulation or -1 */
@@ -251,6 +250,9 @@ struct x86_emulate_ctxt {
#endif
int x86_decode_insn(struct x86_emulate_ctxt *ctxt);
+#define EMULATION_FAILED -1
+#define EMULATION_OK 0
+#define EMULATION_RESTART 1
int x86_emulate_insn(struct x86_emulate_ctxt *ctxt);
int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
u16 tss_selector, int reason,
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 922f874..a4cf1f6 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -438,7 +438,6 @@ static void emulate_exception(struct x86_emulate_ctxt *ctxt, int vec,
ctxt->exception = vec;
ctxt->error_code = error;
ctxt->error_code_valid = valid;
- ctxt->restart = false;
}
static void emulate_gp(struct x86_emulate_ctxt *ctxt, int err)
@@ -2635,9 +2634,6 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt)
struct opcode opcode, *g_mod012, *g_mod3;
struct operand memop = { .type = OP_NONE };
- /* we cannot decode insn before we complete previous rep insn */
- WARN_ON(ctxt->restart);
-
c->eip = ctxt->eip;
c->fetch.start = c->fetch.end = c->eip;
ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
@@ -2990,10 +2986,8 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
}
if (c->rep_prefix && (c->d & String)) {
- ctxt->restart = true;
/* All REP prefixes have the same first termination condition */
if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) {
- ctxt->restart = false;
ctxt->eip = c->eip;
goto done;
}
@@ -3449,28 +3443,29 @@ writeback:
struct read_cache *r = &ctxt->decode.io_read;
register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
- if (string_insn_completed(ctxt))
- ctxt->restart = false;
- /*
- * Re-enter guest when pio read ahead buffer is empty or,
- * if it is not used, after each 1024 iteration.
- */
- else if ((r->end == 0 && !(c->regs[VCPU_REGS_RCX] & 0x3ff)) ||
- (r->end != 0 && r->end == r->pos)) {
- ctxt->restart = false;
- c->eip = ctxt->eip;
+ if (!string_insn_completed(ctxt)) {
+ /*
+ * Re-enter guest when pio read ahead buffer is empty
+ * or, if it is not used, after each 1024 iteration.
+ */
+ if ((r->end != 0 || c->regs[VCPU_REGS_RCX] & 0x3ff) &&
+ (r->end == 0 || r->end != r->pos)) {
+ /*
+ * Reset read cache. Usually happens before
+ * decode, but since instruction is restarted
+ * we have to do it here.
+ */
+ ctxt->decode.mem_read.end = 0;
+ return EMULATION_RESTART;
+ }
+ goto done; /* skip rip writeback */
}
}
- /*
- * reset read cache here in case string instruction is restared
- * without decoding
- */
- ctxt->decode.mem_read.end = 0;
- if (!ctxt->restart)
- ctxt->eip = c->eip;
+
+ ctxt->eip = c->eip;
done:
- return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+ return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
twobyte_insn:
switch (c->b) {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 524bd3f..112213e 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4171,18 +4171,17 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
restart:
r = x86_emulate_insn(&vcpu->arch.emulate_ctxt);
- if (r) { /* emulation failed */
+ if (r == EMULATION_FAILED) {
if (reexecute_instruction(vcpu, cr2))
return EMULATE_DONE;
return handle_emulation_failure(vcpu);
}
- r = EMULATE_DONE;
-
- if (vcpu->arch.emulate_ctxt.exception >= 0)
+ if (vcpu->arch.emulate_ctxt.exception >= 0) {
inject_emulated_exception(vcpu);
- else if (vcpu->arch.pio.count) {
+ r = EMULATE_DONE;
+ } else if (vcpu->arch.pio.count) {
if (!vcpu->arch.pio.in)
vcpu->arch.pio.count = 0;
r = EMULATE_DO_MMIO;
@@ -4190,8 +4189,10 @@ restart:
if (vcpu->mmio_is_write)
vcpu->mmio_needed = 0;
r = EMULATE_DO_MMIO;
- } else if (vcpu->arch.emulate_ctxt.restart)
+ } else if (r == EMULATION_RESTART)
goto restart;
+ else
+ r = EMULATE_DONE;
toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility);
kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
@@ -5090,8 +5091,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
if (!irqchip_in_kernel(vcpu->kvm))
kvm_set_cr8(vcpu, kvm_run->cr8);
- if (vcpu->arch.pio.count || vcpu->mmio_needed ||
- vcpu->arch.emulate_ctxt.restart) {
+ if (vcpu->arch.pio.count || vcpu->mmio_needed) {
if (vcpu->mmio_needed) {
memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
vcpu->mmio_read_completed = 1;
--
1.7.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCHv2 3/3] KVM: x86 emulator: get rid of "restart" in emulation context.
2010-08-25 9:47 ` [PATCHv2 3/3] KVM: x86 emulator: get rid of "restart" in emulation context Gleb Natapov
@ 2010-08-25 10:36 ` Avi Kivity
0 siblings, 0 replies; 5+ messages in thread
From: Avi Kivity @ 2010-08-25 10:36 UTC (permalink / raw)
To: Gleb Natapov; +Cc: mtosatti, kvm
On 08/25/2010 12:47 PM, Gleb Natapov wrote:
> x86_emulate_insn() will return 1 if instruction can be restarted
> without re-entering a guest.
Looks good.
--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable.
2010-08-25 9:47 [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable Gleb Natapov
2010-08-25 9:47 ` [PATCHv2 2/3] KVM: x86 emulator: move string instruction completion check into separate function Gleb Natapov
2010-08-25 9:47 ` [PATCHv2 3/3] KVM: x86 emulator: get rid of "restart" in emulation context Gleb Natapov
@ 2010-08-26 15:23 ` Marcelo Tosatti
2 siblings, 0 replies; 5+ messages in thread
From: Marcelo Tosatti @ 2010-08-26 15:23 UTC (permalink / raw)
To: Gleb Natapov; +Cc: avi, kvm
On Wed, Aug 25, 2010 at 12:47:41PM +0300, Gleb Natapov wrote:
>
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> ---
> arch/x86/kvm/emulate.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
Applied all, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-08-26 17:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-25 9:47 [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable Gleb Natapov
2010-08-25 9:47 ` [PATCHv2 2/3] KVM: x86 emulator: move string instruction completion check into separate function Gleb Natapov
2010-08-25 9:47 ` [PATCHv2 3/3] KVM: x86 emulator: get rid of "restart" in emulation context Gleb Natapov
2010-08-25 10:36 ` Avi Kivity
2010-08-26 15:23 ` [PATCHv2 1/3] KVM: x86 emulator: Rename variable that shadows another local variable Marcelo Tosatti
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.