aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-03-21 07:08:20 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:16:35 -0400
commit482ac18ae293a3a0b1e1eea95c10dcc9ceeb4708 (patch)
tree73e6dde8b669cef33edfd9de2074763b44bb6a1f
parent9749a6c0f0a4f88ae7bad4f65d7da32769e9b2b7 (diff)
KVM: x86 emulator: commit rflags as part of registers commit
Make sure that rflags is committed only after successful instruction emulation. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/include/asm/kvm_emulate.h1
-rw-r--r--arch/x86/kvm/emulate.c1
-rw-r--r--arch/x86/kvm/x86.c8
3 files changed, 8 insertions, 2 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index b5e12c58386..a1319c82050 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -136,6 +136,7 @@ struct x86_emulate_ops {
136 ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu); 136 ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu);
137 void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu); 137 void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu);
138 int (*cpl)(struct kvm_vcpu *vcpu); 138 int (*cpl)(struct kvm_vcpu *vcpu);
139 void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
139}; 140};
140 141
141/* Type, address-of, and value of an instruction's operand. */ 142/* Type, address-of, and value of an instruction's operand. */
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index ab3fff5bf7c..48de4b89005 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2972,6 +2972,7 @@ writeback:
2972 /* Commit shadow register state. */ 2972 /* Commit shadow register state. */
2973 memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs); 2973 memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);
2974 kvm_rip_write(ctxt->vcpu, c->eip); 2974 kvm_rip_write(ctxt->vcpu, c->eip);
2975 ops->set_rflags(ctxt->vcpu, ctxt->eflags);
2975 2976
2976done: 2977done:
2977 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; 2978 return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b4d3363b78e..247e805a041 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3649,6 +3649,11 @@ static void emulator_set_segment_selector(u16 sel, int seg,
3649 kvm_set_segment(vcpu, &kvm_seg, seg); 3649 kvm_set_segment(vcpu, &kvm_seg, seg);
3650} 3650}
3651 3651
3652static void emulator_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
3653{
3654 kvm_x86_ops->set_rflags(vcpu, rflags);
3655}
3656
3652static struct x86_emulate_ops emulate_ops = { 3657static struct x86_emulate_ops emulate_ops = {
3653 .read_std = kvm_read_guest_virt_system, 3658 .read_std = kvm_read_guest_virt_system,
3654 .write_std = kvm_write_guest_virt_system, 3659 .write_std = kvm_write_guest_virt_system,
@@ -3666,6 +3671,7 @@ static struct x86_emulate_ops emulate_ops = {
3666 .get_cr = emulator_get_cr, 3671 .get_cr = emulator_get_cr,
3667 .set_cr = emulator_set_cr, 3672 .set_cr = emulator_set_cr,
3668 .cpl = emulator_get_cpl, 3673 .cpl = emulator_get_cpl,
3674 .set_rflags = emulator_set_rflags,
3669}; 3675};
3670 3676
3671static void cache_all_regs(struct kvm_vcpu *vcpu) 3677static void cache_all_regs(struct kvm_vcpu *vcpu)
@@ -3786,8 +3792,6 @@ restart:
3786 return EMULATE_DO_MMIO; 3792 return EMULATE_DO_MMIO;
3787 } 3793 }
3788 3794
3789 kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
3790
3791 if (vcpu->mmio_is_write) { 3795 if (vcpu->mmio_is_write) {
3792 vcpu->mmio_needed = 0; 3796 vcpu->mmio_needed = 0;
3793 return EMULATE_DO_MMIO; 3797 return EMULATE_DO_MMIO;