diff options
author | Avi Kivity <avi@redhat.com> | 2010-08-17 04:17:51 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-10-24 04:51:09 -0400 |
commit | 5c56e1cf7a758c4772e2470b4346a8219ec7f44e (patch) | |
tree | 4ccb17fadcd358011627469a6b995897e14e63a7 /arch/x86/kvm/emulate.c | |
parent | a13a63faa6237001ed80d4f4051fc028dace10d9 (diff) |
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: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index cffe7c2819ed..b89a20ec7c9d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1232,7 +1232,7 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt, | |||
1232 | struct x86_emulate_ops *ops, int irq) | 1232 | struct x86_emulate_ops *ops, int irq) |
1233 | { | 1233 | { |
1234 | struct decode_cache *c = &ctxt->decode; | 1234 | struct decode_cache *c = &ctxt->decode; |
1235 | int rc = X86EMUL_CONTINUE; | 1235 | int rc; |
1236 | struct desc_ptr dt; | 1236 | struct desc_ptr dt; |
1237 | gva_t cs_addr; | 1237 | gva_t cs_addr; |
1238 | gva_t eip_addr; | 1238 | gva_t eip_addr; |
@@ -1242,14 +1242,25 @@ int emulate_int_real(struct x86_emulate_ctxt *ctxt, | |||
1242 | /* TODO: Add limit checks */ | 1242 | /* TODO: Add limit checks */ |
1243 | c->src.val = ctxt->eflags; | 1243 | c->src.val = ctxt->eflags; |
1244 | emulate_push(ctxt, ops); | 1244 | emulate_push(ctxt, ops); |
1245 | rc = writeback(ctxt, ops); | ||
1246 | if (rc != X86EMUL_CONTINUE) | ||
1247 | return rc; | ||
1245 | 1248 | ||
1246 | ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC); | 1249 | ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC); |
1247 | 1250 | ||
1248 | c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); | 1251 | c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu); |
1249 | emulate_push(ctxt, ops); | 1252 | emulate_push(ctxt, ops); |
1253 | rc = writeback(ctxt, ops); | ||
1254 | if (rc != X86EMUL_CONTINUE) | ||
1255 | return rc; | ||
1250 | 1256 | ||
1251 | c->src.val = c->eip; | 1257 | c->src.val = c->eip; |
1252 | emulate_push(ctxt, ops); | 1258 | emulate_push(ctxt, ops); |
1259 | rc = writeback(ctxt, ops); | ||
1260 | if (rc != X86EMUL_CONTINUE) | ||
1261 | return rc; | ||
1262 | |||
1263 | c->dst.type = OP_NONE; | ||
1253 | 1264 | ||
1254 | ops->get_idt(&dt, ctxt->vcpu); | 1265 | ops->get_idt(&dt, ctxt->vcpu); |
1255 | 1266 | ||