• Marcelo Tosatti's avatar
    KVM: IOAPIC: only set remote_irr if interrupt was injected · ff4b9df8
    Marcelo Tosatti authored
    There's a bug in the IOAPIC code for level-triggered interrupts. Its
    relatively easy to trigger by sharing (virtio-blk + usbtablet was the
    testcase, initially reported by Gerd von Egidy).
    
    The "remote_irr" variable is used to indicate accepted but not yet acked
    interrupts. Its cleared from the EOI handler.
    
    Problem is that the EOI handler clears remote_irr unconditionally, even
    if it reinjected another pending interrupt.
    
    In that case, kvm_ioapic_set_irq() proceeds to ioapic_service() which
    sets remote_irr even if it failed to inject (since the IRR was high due
    to EOI reinjection).
    
    Since the TMR bit has been cleared by the first EOI, the second one
    fails to clear remote_irr.
    
    End result is interrupt line dead.
    
    Fix it by setting remote_irr only if a new pending interrupt has been
    generated (and the TMR bit for vector in question set).
    Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
    Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
    ff4b9df8
ioapic.c 9.88 KB