lkml.org 
[lkml]   [2017]   [Dec]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 17/38] KVM: lapic: Fixup LDR on load in x2apic
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Dr. David Alan Gilbert <dgilbert@redhat.com>

    commit 12806ba937382fdfdbad62a399aa2dce65c10fcd upstream.

    In x2apic mode the LDR is fixed based on the ID rather
    than separately loadable like it was before x2.
    When kvm_apic_set_state is called, the base is set, and if
    it has the X2APIC_ENABLE flag set then the LDR is calculated;
    however that value gets overwritten by the memcpy a few lines
    below overwriting it with the value that came from userland.

    The symptom is a lack of EOI after loading the state
    (e.g. after a QEMU migration) and is due to the EOI bitmap
    being wrong due to the incorrect LDR. This was seen with
    a Win2016 guest under Qemu with irqchip=split whose USB mouse
    didn't work after a VM migration.

    This corresponds to RH bug:
    https://bugzilla.redhat.com/show_bug.cgi?id=1502591

    Reported-by: Yiqian Wei <yiwei@redhat.com>
    Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
    [Applied fixup from Liran Alon. - Paolo]
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/x86/kvm/lapic.c | 5 +++++
    1 file changed, 5 insertions(+)

    --- a/arch/x86/kvm/lapic.c
    +++ b/arch/x86/kvm/lapic.c
    @@ -2034,6 +2034,7 @@ static int kvm_apic_state_fixup(struct k
    {
    if (apic_x2apic_mode(vcpu->arch.apic)) {
    u32 *id = (u32 *)(s->regs + APIC_ID);
    + u32 *ldr = (u32 *)(s->regs + APIC_LDR);

    if (vcpu->kvm->arch.x2apic_format) {
    if (*id != vcpu->vcpu_id)
    @@ -2044,6 +2045,10 @@ static int kvm_apic_state_fixup(struct k
    else
    *id <<= 24;
    }
    +
    + /* In x2APIC mode, the LDR is fixed and based on the id */
    + if (set)
    + *ldr = kvm_apic_calc_x2apic_ldr(*id);
    }

    return 0;

    \
     
     \ /
      Last update: 2017-12-04 17:35    [W:2.430 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site