aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3adf6921e88e..7d2880500fa3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4188,6 +4188,35 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu)
4188 memcpy(c->regs, vcpu->arch.regs, sizeof c->regs); 4188 memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
4189} 4189}
4190 4190
4191int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq)
4192{
4193 struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
4194 int ret;
4195
4196 init_emulate_ctxt(vcpu);
4197
4198 vcpu->arch.emulate_ctxt.decode.op_bytes = 2;
4199 vcpu->arch.emulate_ctxt.decode.ad_bytes = 2;
4200 vcpu->arch.emulate_ctxt.decode.eip = vcpu->arch.emulate_ctxt.eip;
4201 ret = emulate_int_real(&vcpu->arch.emulate_ctxt, &emulate_ops, irq);
4202
4203 if (ret != X86EMUL_CONTINUE)
4204 return EMULATE_FAIL;
4205
4206 vcpu->arch.emulate_ctxt.eip = c->eip;
4207 memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
4208 kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
4209 kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
4210
4211 if (irq == NMI_VECTOR)
4212 vcpu->arch.nmi_pending = false;
4213 else
4214 vcpu->arch.interrupt.pending = false;
4215
4216 return EMULATE_DONE;
4217}
4218EXPORT_SYMBOL_GPL(kvm_inject_realmode_interrupt);
4219
4191static int handle_emulation_failure(struct kvm_vcpu *vcpu) 4220static int handle_emulation_failure(struct kvm_vcpu *vcpu)
4192{ 4221{
4193 ++vcpu->stat.insn_emulation_fail; 4222 ++vcpu->stat.insn_emulation_fail;