• Paolo Bonzini's avatar
    kvm: ioapic: Restrict lazy EOI update to edge-triggered interrupts · 8be8f932
    Paolo Bonzini authored
    Commit f458d039 ("kvm: ioapic: Lazy update IOAPIC EOI") introduces
    the following infinite loop:
    
    BUG: stack guard page was hit at 000000008f595917 \
    (stack is 00000000bdefe5a4..00000000ae2b06f5)
    kernel stack overflow (double-fault): 0000 [#1] SMP NOPTI
    RIP: 0010:kvm_set_irq+0x51/0x160 [kvm]
    Call Trace:
     irqfd_resampler_ack+0x32/0x90 [kvm]
     kvm_notify_acked_irq+0x62/0xd0 [kvm]
     kvm_ioapic_update_eoi_one.isra.0+0x30/0x120 [kvm]
     ioapic_set_irq+0x20e/0x240 [kvm]
     kvm_ioapic_set_irq+0x5c/0x80 [kvm]
     kvm_set_irq+0xbb/0x160 [kvm]
     ? kvm_hv_set_sint+0x20/0x20 [kvm]
     irqfd_resampler_ack+0x32/0x90 [kvm]
     kvm_notify_acked_irq+0x62/0xd0 [kvm]
     kvm_ioapic_update_eoi_one.isra.0+0x30/0x120 [kvm]
     ioapic_set_irq+0x20e/0x240 [kvm]
     kvm_ioapic_set_irq+0x5c/0x80 [kvm]
     kvm_set_irq+0xbb/0x160 [kvm]
     ? kvm_hv_set_sint+0x20/0x20 [kvm]
    ....
    
    The re-entrancy happens because the irq state is the OR of
    the interrupt state and the resamplefd state.  That is, we don't
    want to show the state as 0 until we've had a chance to set the
    resamplefd.  But if the interrupt has _not_ gone low then
    ioapic_set_irq is invoked again, causing an infinite loop.
    
    This can only happen for a level-triggered interrupt, otherwise
    irqfd_inject would immediately set the KVM_USERSPACE_IRQ_SOURCE_ID high
    and then low.  Fortunately, in the case of level-triggered interrupts the VMEXIT already happens because
    TMR is set.  Thus, fix the bug by restricting the lazy invocation
    of the ack notifier to edge-triggered interrupts, the only ones that
    need it.
    Tested-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
    Reported-by: borisvk@bstnet.org
    Suggested-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Link: https://www.spinics.net/lists/kvm/msg213512.html
    Fixes: f458d039 ("kvm: ioapic: Lazy update IOAPIC EOI")
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=207489Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    8be8f932
ioapic.c 19.7 KB