]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
KVM: SVM: Fix potential wrong physical id in avic_handle_ldr_update
authorMiaohe Lin <linmiaohe@huawei.com>
Fri, 18 Oct 2019 02:50:31 +0000 (10:50 +0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 22 Oct 2019 16:47:50 +0000 (18:47 +0200)
Guest physical APIC ID may not equal to vcpu->vcpu_id in some case.
We may set the wrong physical id in avic_handle_ldr_update as we
always use vcpu->vcpu_id. Get physical APIC ID from vAPIC page
instead.
Export and use kvm_xapic_id here and in avic_handle_apic_id_update
as suggested by Vitaly.

Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/lapic.c
arch/x86/kvm/lapic.h
arch/x86/kvm/svm.c

index 87b0fcc23ef8946f7fe2f7ab46db9c0178a706b9..b29d00b661ff2155a3530bd6eeb094287a981f37 100644 (file)
@@ -111,11 +111,6 @@ static inline int apic_enabled(struct kvm_lapic *apic)
        (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
         APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
 
-static inline u8 kvm_xapic_id(struct kvm_lapic *apic)
-{
-       return kvm_lapic_get_reg(apic, APIC_ID) >> 24;
-}
-
 static inline u32 kvm_x2apic_id(struct kvm_lapic *apic)
 {
        return apic->vcpu->vcpu_id;
index 2aad7e226fc016e130f29746f4fa2798fb811126..1f5014852e208e1c38c9d0c7c57fa0ae8fc6d110 100644 (file)
@@ -242,4 +242,9 @@ static inline enum lapic_mode kvm_apic_mode(u64 apic_base)
        return apic_base & (MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE);
 }
 
+static inline u8 kvm_xapic_id(struct kvm_lapic *apic)
+{
+       return kvm_lapic_get_reg(apic, APIC_ID) >> 24;
+}
+
 #endif
index f8ecb6df5106641517a75380e4755dfa65967f08..ca200b50cde4d1a178a47099e02e164b7a29e840 100644 (file)
@@ -4591,6 +4591,7 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu)
        int ret = 0;
        struct vcpu_svm *svm = to_svm(vcpu);
        u32 ldr = kvm_lapic_get_reg(vcpu->arch.apic, APIC_LDR);
+       u32 id = kvm_xapic_id(vcpu->arch.apic);
 
        if (ldr == svm->ldr_reg)
                return 0;
@@ -4598,7 +4599,7 @@ static int avic_handle_ldr_update(struct kvm_vcpu *vcpu)
        avic_invalidate_logical_id_entry(vcpu);
 
        if (ldr)
-               ret = avic_ldr_write(vcpu, vcpu->vcpu_id, ldr);
+               ret = avic_ldr_write(vcpu, id, ldr);
 
        if (!ret)
                svm->ldr_reg = ldr;
@@ -4610,8 +4611,7 @@ static int avic_handle_apic_id_update(struct kvm_vcpu *vcpu)
 {
        u64 *old, *new;
        struct vcpu_svm *svm = to_svm(vcpu);
-       u32 apic_id_reg = kvm_lapic_get_reg(vcpu->arch.apic, APIC_ID);
-       u32 id = (apic_id_reg >> 24) & 0xff;
+       u32 id = kvm_xapic_id(vcpu->arch.apic);
 
        if (vcpu->vcpu_id == id)
                return 0;