aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMohammed Gamal <m.gamal005@gmail.com>2010-09-19 08:34:06 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:53:01 -0400
commit63995653ade16deacaea5b49ceaf6376314593ac (patch)
tree92c4dc379a1c8925a53ce6d6abd5d4d0f85ecc49 /arch
parent4ab8e02404fcbc16beefac66de24dbb2706fe2f3 (diff)
KVM: Add kvm_inject_realmode_interrupt() wrapper
This adds a wrapper function kvm_inject_realmode_interrupt() around the emulator function emulate_int_real() to allow real mode interrupt injection. [avi: initialize operand and address sizes before emulating interrupts] [avi: initialize rip for real mode interrupt injection] [avi: clear interrupt pending flag after emulating interrupt injection] Signed-off-by: Mohammed Gamal <m.gamal005@gmail.com> Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/x86.c29
-rw-r--r--arch/x86/kvm/x86.h1
2 files changed, 30 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;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index bf4dc2f40d7f..2cea414489f3 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -72,6 +72,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
72 72
73void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); 73void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
74void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); 74void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
75int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
75 76
76void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data); 77void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data);
77 78