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;