Skip to content

Commit 1808c95

Browse files
sean-jcbonzini
authored andcommitted
KVM: SVM: Require logical ID to be power-of-2 for AVIC entry
Do not modify AVIC's logical ID table if the logical ID portion of the LDR is not a power-of-2, i.e. if the LDR has multiple bits set. Taking only the first bit means that KVM will fail to match MDAs that intersect with "higher" bits in the "ID" The "ID" acts as a bitmap, but is referred to as an ID because there's an implicit, unenforced "requirement" that software only set one bit. This edge case is arguably out-of-spec behavior, but KVM cleanly handles it in all other cases, e.g. the optimized logical map (and AVIC!) is also disabled in this scenario. Refactor the code to consolidate the checks, and so that the code looks more like avic_kick_target_vcpus_fast(). Fixes: 18f40c5 ("svm: Add VMEXIT handlers for AVIC") Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Cc: Maxim Levitsky <mlevitsk@redhat.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-Id: <20230106011306.85230-28-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 4f160b7 commit 1808c95

File tree

1 file changed

+15
-15
lines changed

1 file changed

+15
-15
lines changed

arch/x86/kvm/svm/avic.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -513,26 +513,26 @@ unsigned long avic_vcpu_get_apicv_inhibit_reasons(struct kvm_vcpu *vcpu)
513513
static u32 *avic_get_logical_id_entry(struct kvm_vcpu *vcpu, u32 ldr, bool flat)
514514
{
515515
struct kvm_svm *kvm_svm = to_kvm_svm(vcpu->kvm);
516-
int index;
517516
u32 *logical_apic_id_table;
518-
int dlid = GET_APIC_LOGICAL_ID(ldr);
517+
u32 cluster, index;
519518

520-
if (!dlid)
521-
return NULL;
522-
523-
if (flat) { /* flat */
524-
index = ffs(dlid) - 1;
525-
if (index > 7)
526-
return NULL;
527-
} else { /* cluster */
528-
int cluster = (dlid & 0xf0) >> 4;
529-
int apic = ffs(dlid & 0x0f) - 1;
519+
ldr = GET_APIC_LOGICAL_ID(ldr);
530520

531-
if ((apic < 0) || (apic > 7) ||
532-
(cluster >= 0xf))
521+
if (flat) {
522+
cluster = 0;
523+
} else {
524+
cluster = (ldr >> 4);
525+
if (cluster >= 0xf)
533526
return NULL;
534-
index = (cluster << 2) + apic;
527+
ldr &= 0xf;
535528
}
529+
if (!ldr || !is_power_of_2(ldr))
530+
return NULL;
531+
532+
index = __ffs(ldr);
533+
if (WARN_ON_ONCE(index > 7))
534+
return NULL;
535+
index += (cluster << 2);
536536

537537
logical_apic_id_table = (u32 *) page_address(kvm_svm->avic_logical_id_table_page);
538538

0 commit comments

Comments
 (0)