From 86a24feec1919b7858bb1062d5160f0e12aa5c7d Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 23 Sep 2026 08:51:06 -0700 Subject: [PATCH] KVM: SVM: Add paranoid helper for checking if vCPU is AVIC-addressable Add a helper to check if a vCPU is addressable by AVIC hardware, i.e. has an APIC ID that fits in the physical ID table, and use the more paranoid helper when determining if a vCPU is compatible with AVIC when initializing the vCPU. KVM is supposed to reject vCPU creation if the vCPU's ID is greater than or equal to max_vcpu_ids, i.e. simply checking the architectural maximum *should* suffice. But piecing together why this is safe is unnecessarily difficult, and there is no meaningful downside to being extra cautious. Suggested-by: Naveen N Rao (AMD) Reviewed-by: Naveen N Rao (AMD) Link: https://patch.msgid.link/20260923155108.1550622-2-seanjc@google.com Signed-off-by: Sean Christopherson --- arch/x86/kvm/svm/avic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index 3b037e385523..0e4b5eb6ac82 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -395,6 +395,11 @@ static phys_addr_t avic_get_backing_page_address(struct vcpu_svm *svm) return __sme_set(__pa(svm->vcpu.arch.apic->regs)); } +static bool avic_is_addressable_vcpu(struct kvm_vcpu *vcpu) +{ + return vcpu->vcpu_id <= __avic_get_max_physical_id(vcpu->kvm, NULL); +} + void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb) { struct kvm_svm *kvm_svm = to_kvm_svm(svm->vcpu.kvm); @@ -412,7 +417,6 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb) static int avic_init_backing_page(struct kvm_vcpu *vcpu) { - u32 max_id = x2avic_enabled ? x2avic_max_physical_id : AVIC_MAX_PHYSICAL_ID; struct kvm_svm *kvm_svm = to_kvm_svm(vcpu->kvm); struct vcpu_svm *svm = to_svm(vcpu); u32 id = vcpu->vcpu_id; @@ -425,7 +429,7 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu) * avic_vcpu_load() expects to be called if and only if the vCPU has * fully initialized AVIC. */ - if (id > max_id) { + if (!avic_is_addressable_vcpu(vcpu)) { kvm_set_apicv_inhibit(vcpu->kvm, APICV_INHIBIT_REASON_PHYSICAL_ID_TOO_BIG); vcpu->arch.apic->apicv_active = false; return 0;