lkml.org 
[lkml]   [2020]   [Dec]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 024/152] KVM: x86: handle !lapic_in_kernel case in kvm_cpu_*_extint
    Date
    From: Paolo Bonzini <pbonzini@redhat.com>

    commit 72c3bcdcda494cbd600712a32e67702cdee60c07 upstream.

    Centralize handling of interrupts from the userspace APIC
    in kvm_cpu_has_extint and kvm_cpu_get_extint, since
    userspace APIC interrupts are handled more or less the
    same as ExtINTs are with split irqchip. This removes
    duplicated code from kvm_cpu_has_injectable_intr and
    kvm_cpu_has_interrupt, and makes the code more similar
    between kvm_cpu_has_{extint,interrupt} on one side
    and kvm_cpu_get_{extint,interrupt} on the other.

    Cc: stable@vger.kernel.org
    Reviewed-by: Filippo Sironi <sironi@amazon.de>
    Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
    Tested-by: David Woodhouse <dwmw@amazon.co.uk>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/kvm/irq.c | 83 ++++++++++++++++++++-------------------------------
    arch/x86/kvm/lapic.c | 2 -
    2 files changed, 34 insertions(+), 51 deletions(-)

    --- a/arch/x86/kvm/irq.c
    +++ b/arch/x86/kvm/irq.c
    @@ -42,27 +42,8 @@ static int pending_userspace_extint(stru
    */
    static int kvm_cpu_has_extint(struct kvm_vcpu *v)
    {
    - u8 accept = kvm_apic_accept_pic_intr(v);
    -
    - if (accept) {
    - if (irqchip_split(v->kvm))
    - return pending_userspace_extint(v);
    - else
    - return v->kvm->arch.vpic->output;
    - } else
    - return 0;
    -}
    -
    -/*
    - * check if there is injectable interrupt:
    - * when virtual interrupt delivery enabled,
    - * interrupt from apic will handled by hardware,
    - * we don't need to check it here.
    - */
    -int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
    -{
    /*
    - * FIXME: interrupt.injected represents an interrupt that it's
    + * FIXME: interrupt.injected represents an interrupt whose
    * side-effects have already been applied (e.g. bit from IRR
    * already moved to ISR). Therefore, it is incorrect to rely
    * on interrupt.injected to know if there is a pending
    @@ -75,6 +56,23 @@ int kvm_cpu_has_injectable_intr(struct k
    if (!lapic_in_kernel(v))
    return v->arch.interrupt.injected;

    + if (!kvm_apic_accept_pic_intr(v))
    + return 0;
    +
    + if (irqchip_split(v->kvm))
    + return pending_userspace_extint(v);
    + else
    + return v->kvm->arch.vpic->output;
    +}
    +
    +/*
    + * check if there is injectable interrupt:
    + * when virtual interrupt delivery enabled,
    + * interrupt from apic will handled by hardware,
    + * we don't need to check it here.
    + */
    +int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
    +{
    if (kvm_cpu_has_extint(v))
    return 1;

    @@ -91,20 +89,6 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_injectable
    */
    int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
    {
    - /*
    - * FIXME: interrupt.injected represents an interrupt that it's
    - * side-effects have already been applied (e.g. bit from IRR
    - * already moved to ISR). Therefore, it is incorrect to rely
    - * on interrupt.injected to know if there is a pending
    - * interrupt in the user-mode LAPIC.
    - * This leads to nVMX/nSVM not be able to distinguish
    - * if it should exit from L2 to L1 on EXTERNAL_INTERRUPT on
    - * pending interrupt or should re-inject an injected
    - * interrupt.
    - */
    - if (!lapic_in_kernel(v))
    - return v->arch.interrupt.injected;
    -
    if (kvm_cpu_has_extint(v))
    return 1;

    @@ -118,16 +102,21 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt)
    */
    static int kvm_cpu_get_extint(struct kvm_vcpu *v)
    {
    - if (kvm_cpu_has_extint(v)) {
    - if (irqchip_split(v->kvm)) {
    - int vector = v->arch.pending_external_vector;
    -
    - v->arch.pending_external_vector = -1;
    - return vector;
    - } else
    - return kvm_pic_read_irq(v->kvm); /* PIC */
    - } else
    + if (!kvm_cpu_has_extint(v)) {
    + WARN_ON(!lapic_in_kernel(v));
    return -1;
    + }
    +
    + if (!lapic_in_kernel(v))
    + return v->arch.interrupt.nr;
    +
    + if (irqchip_split(v->kvm)) {
    + int vector = v->arch.pending_external_vector;
    +
    + v->arch.pending_external_vector = -1;
    + return vector;
    + } else
    + return kvm_pic_read_irq(v->kvm); /* PIC */
    }

    /*
    @@ -135,13 +124,7 @@ static int kvm_cpu_get_extint(struct kvm
    */
    int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
    {
    - int vector;
    -
    - if (!lapic_in_kernel(v))
    - return v->arch.interrupt.nr;
    -
    - vector = kvm_cpu_get_extint(v);
    -
    + int vector = kvm_cpu_get_extint(v);
    if (vector != -1)
    return vector; /* PIC */

    --- a/arch/x86/kvm/lapic.c
    +++ b/arch/x86/kvm/lapic.c
    @@ -2461,7 +2461,7 @@ int kvm_apic_has_interrupt(struct kvm_vc
    struct kvm_lapic *apic = vcpu->arch.apic;
    u32 ppr;

    - if (!kvm_apic_hw_enabled(apic))
    + if (!kvm_apic_present(vcpu))
    return -1;

    __apic_update_ppr(apic, &ppr);

    \
     
     \ /
      Last update: 2020-12-01 10:41    [W:6.680 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site