• Liran Alon's avatar
    KVM: nVMX: Fix injection to L2 when L1 don't intercept external-interrupts · 851c1a18
    Liran Alon authored
    Before each vmentry to guest, vcpu_enter_guest() calls sync_pir_to_irr()
    which calls vmx_hwapic_irr_update() to update RVI.
    Currently, vmx_hwapic_irr_update() contains a tweak in case it is called
    when CPU is running L2 and L1 don't intercept external-interrupts.
    In that case, code injects interrupt directly into L2 instead of
    updating RVI.
    
    Besides being hacky (wouldn't expect function updating RVI to also
    inject interrupt), it also doesn't handle this case correctly.
    The code contains several issues:
    1. When code calls kvm_queue_interrupt() it just passes it max_irr which
    represents the highest IRR currently pending in L1 LAPIC.
    This is problematic as interrupt was injected to guest but it's bit is
    still set in LAPIC IRR instead of being cleared from IRR and set in ISR.
    2. Code doesn't check if LAPIC PPR is set to accept an interrupt of
    max_irr priority. It just checks if interrupts are enabled in guest with
    vmx_interrupt_allowed().
    
    To fix the above issues:
    1. Simplify vmx_hwapic_irr_update() to just update RVI.
    Note that this shouldn't happen when CPU is running L2
    (See comment in code).
    2. Since now vmx_hwapic_irr_update() only does logic for L1
    virtual-interrupt-delivery, inject_pending_event() should be the
    one responsible for injecting the interrupt directly into L2.
    Therefore, change kvm_cpu_has_injectable_intr() to check L1
    LAPIC when CPU is running L2.
    3. Change vmx_sync_pir_to_irr() to set KVM_REQ_EVENT when L1
    has a pending injectable interrupt.
    
    Fixes: 963fee16 ("KVM: nVMX: Fix virtual interrupt delivery
    injection")
    Signed-off-by: default avatarLiran Alon <liran.alon@oracle.com>
    Reviewed-by: default avatarNikita Leshenko <nikita.leshchenko@oracle.com>
    Reviewed-by: default avatarKrish Sadhukhan <krish.sadhukhan@oracle.com>
    Reviewed-by: default avatarLiam Merwick <liam.merwick@oracle.com>
    Signed-off-by: default avatarLiam Merwick <liam.merwick@oracle.com>
    Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarRadim Krčmář <rkrcmar@redhat.com>
    851c1a18
vmx.c 346 KB