Commit 5c56e1cf authored by Avi Kivity's avatar Avi Kivity

KVM: x86 emulator: fix INTn emulation not pushing EFLAGS and CS

emulate_push() only schedules a push; it doesn't actually push anything.
Call writeback() to flush out the write.
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent a13a63fa
...@@ -1232,7 +1232,7 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt, ...@@ -1232,7 +1232,7 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
struct x86_emulate_ops *ops, int irq) struct x86_emulate_ops *ops, int irq)
{ {
struct decode_cache *c = &ctxt->decode; struct decode_cache *c = &ctxt->decode;
int rc = X86EMUL_CONTINUE; int rc;
struct desc_ptr dt; struct desc_ptr dt;
gva_t cs_addr; gva_t cs_addr;
gva_t eip_addr; gva_t eip_addr;
...@@ -1242,14 +1242,25 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt, ...@@ -1242,14 +1242,25 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt,
/* TODO: Add limit checks */ /* TODO: Add limit checks */
c->src.val = ctxt->eflags; c->src.val = ctxt->eflags;
emulate_push(ctxt, ops); emulate_push(ctxt, ops);
rc = writeback(ctxt, ops);
if (rc != X86EMUL_CONTINUE)
return rc;
ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC); ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC);
c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
emulate_push(ctxt, ops); emulate_push(ctxt, ops);
rc = writeback(ctxt, ops);
if (rc != X86EMUL_CONTINUE)
return rc;
c->src.val = c->eip; c->src.val = c->eip;
emulate_push(ctxt, ops); 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); ops->get_idt(&dt, ctxt->vcpu);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment