Index: linux/drivers/kvm/vmx.c =================================================================== --- linux/drivers/kvm/vmx.c (revision 3989) +++ linux/drivers/kvm/vmx.c (working copy) @@ -1163,6 +1163,7 @@ vmcs_writel(VM_EXIT_MSR_LOAD_ADDR, virt_to_phys(vcpu->host_msrs + NR_BAD_MSRS)); vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS_MSR, VM_EXIT_CONTROLS, + VM_EXIT_ACK_INTR_ON_EXIT | (HOST_IS_64 << 9)); /* 22.2,1, 20.7.1 */ vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */ vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */ @@ -1380,7 +1381,24 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { + unsigned long irq; + ++kvm_stat.irq_exits; + irq = vmcs_read32(VM_EXIT_INTR_INFO) & 0xff; + asm volatile ( + "lea irq_dispatch(%0,%0,2), %0 \n\t" + "call *%0 \n\t" + "jmp out \n\t" + "irq_dispatch: \n\t" + "irq = 0 \n\t" + ".rept 256 \n\t" + " .byte 0xcd, irq \n\t" /* avoid int $3 -- one byte opcode */ + " ret \n\t" + " irq = irq + 1 \n\t" + ".endr \n\t" + "out:" + : "+r"(irq) ); + return 1; }