]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
KVM: nVMX: Ack and write vector info to intr_info if L1 asks us to
authorBandan Das <bsd@redhat.com>
Sat, 19 Apr 2014 22:17:45 +0000 (18:17 -0400)
committerMarcelo Tosatti <mtosatti@redhat.com>
Tue, 22 Apr 2014 21:41:33 +0000 (18:41 -0300)
This feature emulates the "Acknowledge interrupt on exit" behavior.
We can safely emulate it for L1 to run L2 even if L0 itself has it
disabled (to run L1).

Signed-off-by: Bandan Das <bsd@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/x86/kvm/irq.c
arch/x86/kvm/vmx.c

index 484bc874688b4ba2bfb8199702671779ffd69d2f..bd0da433e6d72471b259616980cfeac8748bd5cf 100644 (file)
@@ -113,6 +113,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
 
        return kvm_get_apic_interrupt(v);       /* APIC */
 }
+EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt);
 
 void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu)
 {
index f00a6e9021b0f9a0d9fbf535546f98ef5040f582..4378014a41a93a0354c8fabf60bac7aeef3a1ce7 100644 (file)
@@ -4526,6 +4526,16 @@ static bool nested_exit_on_intr(struct kvm_vcpu *vcpu)
                PIN_BASED_EXT_INTR_MASK;
 }
 
+/*
+ * In nested virtualization, check if L1 has set
+ * VM_EXIT_ACK_INTR_ON_EXIT
+ */
+static bool nested_exit_intr_ack_set(struct kvm_vcpu *vcpu)
+{
+       return get_vmcs12(vcpu)->vm_exit_controls &
+               VM_EXIT_ACK_INTR_ON_EXIT;
+}
+
 static bool nested_exit_on_nmi(struct kvm_vcpu *vcpu)
 {
        return get_vmcs12(vcpu)->pin_based_vm_exec_control &
@@ -8563,6 +8573,14 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
        prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info,
                       exit_qualification);
 
+       if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT)
+           && nested_exit_intr_ack_set(vcpu)) {
+               int irq = kvm_cpu_get_interrupt(vcpu);
+               WARN_ON(irq < 0);
+               vmcs12->vm_exit_intr_info = irq |
+                       INTR_INFO_VALID_MASK | INTR_TYPE_EXT_INTR;
+       }
+
        trace_kvm_nested_vmexit_inject(vmcs12->vm_exit_reason,
                                       vmcs12->exit_qualification,
                                       vmcs12->idt_vectoring_info_field,