lkml.org 
[lkml]   [2020]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.5 101/150] KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1
    Date
    From: Vitaly Kuznetsov <vkuznets@redhat.com>

    commit 91a5f413af596ad01097e59bf487eb07cb3f1331 upstream.

    Even when APICv is disabled for L1 it can (and, actually, is) still
    available for L2, this means we need to always call
    vmx_deliver_nested_posted_interrupt() when attempting an interrupt
    delivery.

    Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
    Cc: stable@vger.kernel.org
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/include/asm/kvm_host.h | 2 +-
    arch/x86/kvm/lapic.c | 5 +----
    arch/x86/kvm/svm.c | 7 ++++++-
    arch/x86/kvm/vmx/vmx.c | 13 +++++++++----
    4 files changed, 17 insertions(+), 10 deletions(-)

    --- a/arch/x86/include/asm/kvm_host.h
    +++ b/arch/x86/include/asm/kvm_host.h
    @@ -1115,7 +1115,7 @@ struct kvm_x86_ops {
    void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
    void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
    void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa);
    - void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
    + int (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector);
    int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu);
    int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
    int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr);
    --- a/arch/x86/kvm/lapic.c
    +++ b/arch/x86/kvm/lapic.c
    @@ -1049,11 +1049,8 @@ static int __apic_accept_irq(struct kvm_
    apic->regs + APIC_TMR);
    }

    - if (vcpu->arch.apicv_active)
    - kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
    - else {
    + if (kvm_x86_ops->deliver_posted_interrupt(vcpu, vector)) {
    kvm_lapic_set_irr(vector, apic);
    -
    kvm_make_request(KVM_REQ_EVENT, vcpu);
    kvm_vcpu_kick(vcpu);
    }
    --- a/arch/x86/kvm/svm.c
    +++ b/arch/x86/kvm/svm.c
    @@ -5160,8 +5160,11 @@ static void svm_load_eoi_exitmap(struct
    return;
    }

    -static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
    +static int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
    {
    + if (!vcpu->arch.apicv_active)
    + return -1;
    +
    kvm_lapic_set_irr(vec, vcpu->arch.apic);
    smp_mb__after_atomic();

    @@ -5173,6 +5176,8 @@ static void svm_deliver_avic_intr(struct
    put_cpu();
    } else
    kvm_vcpu_wake_up(vcpu);
    +
    + return 0;
    }

    static bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
    --- a/arch/x86/kvm/vmx/vmx.c
    +++ b/arch/x86/kvm/vmx/vmx.c
    @@ -3848,24 +3848,29 @@ static int vmx_deliver_nested_posted_int
    * 2. If target vcpu isn't running(root mode), kick it to pick up the
    * interrupt from PIR in next vmentry.
    */
    -static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
    +static int vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector)
    {
    struct vcpu_vmx *vmx = to_vmx(vcpu);
    int r;

    r = vmx_deliver_nested_posted_interrupt(vcpu, vector);
    if (!r)
    - return;
    + return 0;
    +
    + if (!vcpu->arch.apicv_active)
    + return -1;

    if (pi_test_and_set_pir(vector, &vmx->pi_desc))
    - return;
    + return 0;

    /* If a previous notification has sent the IPI, nothing to do. */
    if (pi_test_and_set_on(&vmx->pi_desc))
    - return;
    + return 0;

    if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false))
    kvm_vcpu_kick(vcpu);
    +
    + return 0;
    }

    /*

    \
     
     \ /
      Last update: 2020-02-27 15:17    [W:2.395 / U:0.284 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site