Skip to content

Commit 5999715

Browse files
ssuthiku-amdbonzini
authored andcommitted
KVM: SVM: Modify AVIC GATag to support max number of 512 vCPUs
Define AVIC_VCPU_ID_MASK based on AVIC_PHYSICAL_MAX_INDEX, i.e. the mask that effectively controls the largest guest physical APIC ID supported by x2AVIC, instead of hardcoding the number of bits to 8 (and the number of VM bits to 24). The AVIC GATag is programmed into the AMD IOMMU IRTE to provide a reference back to KVM in case the IOMMU cannot inject an interrupt into a non-running vCPU. In such a case, the IOMMU notifies software by creating a GALog entry with the corresponded GATag, and KVM then uses the GATag to find the correct VM+vCPU to kick. Dropping bit 8 from the GATag results in kicking the wrong vCPU when targeting vCPUs with x2APIC ID > 255. Fixes: 4d1d794 ("KVM: SVM: Introduce logic to (de)activate x2AVIC mode") Cc: stable@vger.kernel.org Reported-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Co-developed-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Reviewed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Tested-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Message-Id: <20230207002156.521736-3-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 3ec7a1b commit 5999715

1 file changed

Lines changed: 18 additions & 8 deletions

File tree

arch/x86/kvm/svm/avic.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,29 @@
2727
#include "irq.h"
2828
#include "svm.h"
2929

30-
/* AVIC GATAG is encoded using VM and VCPU IDs */
31-
#define AVIC_VCPU_ID_BITS 8
32-
#define AVIC_VCPU_ID_MASK ((1 << AVIC_VCPU_ID_BITS) - 1)
30+
/*
31+
* Encode the arbitrary VM ID and the vCPU's default APIC ID, i.e the vCPU ID,
32+
* into the GATag so that KVM can retrieve the correct vCPU from a GALog entry
33+
* if an interrupt can't be delivered, e.g. because the vCPU isn't running.
34+
*
35+
* For the vCPU ID, use however many bits are currently allowed for the max
36+
* guest physical APIC ID (limited by the size of the physical ID table), and
37+
* use whatever bits remain to assign arbitrary AVIC IDs to VMs. Note, the
38+
* size of the GATag is defined by hardware (32 bits), but is an opaque value
39+
* as far as hardware is concerned.
40+
*/
41+
#define AVIC_VCPU_ID_MASK AVIC_PHYSICAL_MAX_INDEX_MASK
3342

34-
#define AVIC_VM_ID_BITS 24
35-
#define AVIC_VM_ID_NR (1 << AVIC_VM_ID_BITS)
36-
#define AVIC_VM_ID_MASK ((1 << AVIC_VM_ID_BITS) - 1)
43+
#define AVIC_VM_ID_SHIFT HWEIGHT32(AVIC_PHYSICAL_MAX_INDEX_MASK)
44+
#define AVIC_VM_ID_MASK (GENMASK(31, AVIC_VM_ID_SHIFT) >> AVIC_VM_ID_SHIFT)
3745

38-
#define AVIC_GATAG(x, y) (((x & AVIC_VM_ID_MASK) << AVIC_VCPU_ID_BITS) | \
46+
#define AVIC_GATAG(x, y) (((x & AVIC_VM_ID_MASK) << AVIC_VM_ID_SHIFT) | \
3947
(y & AVIC_VCPU_ID_MASK))
40-
#define AVIC_GATAG_TO_VMID(x) ((x >> AVIC_VCPU_ID_BITS) & AVIC_VM_ID_MASK)
48+
#define AVIC_GATAG_TO_VMID(x) ((x >> AVIC_VM_ID_SHIFT) & AVIC_VM_ID_MASK)
4149
#define AVIC_GATAG_TO_VCPUID(x) (x & AVIC_VCPU_ID_MASK)
4250

51+
static_assert(AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_ID_MASK) == -1u);
52+
4353
static bool force_avic;
4454
module_param_unsafe(force_avic, bool, 0444);
4555

0 commit comments

Comments
 (0)