KVM: x86 emulator: fix INTn emulation not pushing EFLAGS and CS
authorAvi Kivity <avi@redhat.com>
Tue, 17 Aug 2010 08:17:51 +0000 (11:17 +0300)
committerAvi Kivity <avi@redhat.com>
Sun, 24 Oct 2010 08:51:09 +0000 (10:51 +0200)
emulate_push() only schedules a push; it doesn't actually push anything.
Call writeback() to flush out the write.

Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/emulate.c

index cffe7c2819ed98aaf9ecf7cf08f9ff88c803952f..b89a20ec7c9df3c8ecab9b380f3daa0c89b19e7c 100644 (file)
@@ -1232,7 +1232,7 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
                               struct x86_emulate_ops *ops, int irq)
 {
        struct decode_cache *c = &ctxt->decode;
-       int rc = X86EMUL_CONTINUE;
+       int rc;
        struct desc_ptr dt;
        gva_t cs_addr;
        gva_t eip_addr;
@@ -1242,14 +1242,25 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
        /* TODO: Add limit checks */
        c->src.val = ctxt->eflags;
        emulate_push(ctxt, ops);
+       rc = writeback(ctxt, ops);
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
 
        ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC);
 
        c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
        emulate_push(ctxt, ops);
+       rc = writeback(ctxt, ops);
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
 
        c->src.val = c->eip;
        emulate_push(ctxt, ops);
+       rc = writeback(ctxt, ops);
+       if (rc != X86EMUL_CONTINUE)
+               return rc;
+
+       c->dst.type = OP_NONE;
 
        ops->get_idt(&dt, ctxt->vcpu);