Track potential changes to a vCPU's xAPIC ID only for KVM_SET_LAPIC, i.e. not for KVM_GET_LAPIC, and process the update after the incoming state provided by userspace is copied to KVM's in-kernel vAPIC. The latter bug is the most problematic issue, as processing the update before KVM's vAPIC is actually updated can result in false positives, e.g. due to the APIC holding an x2APIC ID (wrong format), and false negatives, e.g. due to KVM failing to detect an xAPIC ID "mismatch". Processing an "update" in KVM_GET_LAPIC is likely a benign bug now that the update helper ignores mismatches, but prior to that fix, invoking KVM_GET_LAPIC while the APIC is disabled could effectively cause KVM to consume stale state, e.g. if the APIC were in x2APIC mode before being hardware disabled. Fixes: 3743c2f02517 ("KVM: x86: inhibit APICv/AVIC on changes to APIC ID or APIC base") Reported-by: Alejandro Jimenez <alejandro.j.jimenez@xxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> --- arch/x86/kvm/lapic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 67260f7ce43a..251856ba0750 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2720,8 +2720,6 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu, icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR); __kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32); } - } else { - kvm_lapic_xapic_id_updated(vcpu->arch.apic); } return 0; @@ -2757,6 +2755,9 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s) } memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s)); + if (!apic_x2apic_mode(vcpu->arch.apic)) + kvm_lapic_xapic_id_updated(vcpu->arch.apic); + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); kvm_recalculate_apic_map(vcpu->kvm); kvm_apic_set_version(vcpu); -- 2.38.0.rc1.362.ged0d419d3c-goog