• Sean Christopherson's avatar
    KVM: nVMX: Get to-be-acknowledge IRQ for nested VM-Exit at injection site · 363010e1
    Sean Christopherson authored
    Move the logic to get the to-be-acknowledge IRQ for a nested VM-Exit from
    nested_vmx_vmexit() to vmx_check_nested_events(), which is subtly the one
    and only path where KVM invokes nested_vmx_vmexit() with
    EXIT_REASON_EXTERNAL_INTERRUPT.  A future fix will perform a last-minute
    check on L2's nested posted interrupt notification vector, just before
    injecting a nested VM-Exit.  To handle that scenario correctly, KVM needs
    to get the interrupt _before_ injecting VM-Exit, as simply querying the
    highest priority interrupt, via kvm_cpu_has_interrupt(), would result in
    TOCTOU bug, as a new, higher priority interrupt could arrive between
    kvm_cpu_has_interrupt() and kvm_cpu_get_interrupt().
    
    Unfortunately, simply moving the call to kvm_cpu_get_interrupt() doesn't
    suffice, as a VMWRITE to GUEST_INTERRUPT_STATUS.SVI is hiding in
    kvm_get_apic_interrupt(), and acknowledging the interrupt before nested
    VM-Exit would cause the VMWRITE to hit vmcs02 instead of vmcs01.
    
    Open code a rough equivalent to kvm_cpu_get_interrupt() so that the IRQ
    is acknowledged after emulating VM-Exit, taking care to avoid the TOCTOU
    issue described above.
    
    Opportunistically convert the WARN_ON() to a WARN_ON_ONCE().  If KVM has
    a bug that results in a false positive from kvm_cpu_has_interrupt(),
    spamming dmesg won't help the situation.
    
    Note, nested_vmx_reflect_vmexit() can never reflect external interrupts as
    they are always "wanted" by L0.
    
    Link: https://lore.kernel.org/r/20240906043413.1049633-3-seanjc@google.comSigned-off-by: default avatarSean Christopherson <seanjc@google.com>
    363010e1
irq.c 3.87 KB