|
30 | 30 | #include "svm.h"
|
31 | 31 |
|
32 | 32 | /*
|
33 |
| - * Encode the arbitrary VM ID and the vCPU's default APIC ID, i.e the vCPU ID, |
34 |
| - * into the GATag so that KVM can retrieve the correct vCPU from a GALog entry |
35 |
| - * if an interrupt can't be delivered, e.g. because the vCPU isn't running. |
| 33 | + * Encode the arbitrary VM ID and the vCPU's _index_ into the GATag so that |
| 34 | + * KVM can retrieve the correct vCPU from a GALog entry if an interrupt can't |
| 35 | + * be delivered, e.g. because the vCPU isn't running. Use the vCPU's index |
| 36 | + * instead of its ID (a.k.a. its default APIC ID), as KVM is guaranteed a fast |
| 37 | + * lookup on the index, where as vCPUs whose index doesn't match their ID need |
| 38 | + * to walk the entire xarray of vCPUs in the worst case scenario. |
36 | 39 | *
|
37 |
| - * For the vCPU ID, use however many bits are currently allowed for the max |
| 40 | + * For the vCPU index, use however many bits are currently allowed for the max |
38 | 41 | * guest physical APIC ID (limited by the size of the physical ID table), and
|
39 | 42 | * use whatever bits remain to assign arbitrary AVIC IDs to VMs. Note, the
|
40 | 43 | * size of the GATag is defined by hardware (32 bits), but is an opaque value
|
41 | 44 | * as far as hardware is concerned.
|
42 | 45 | */
|
43 |
| -#define AVIC_VCPU_ID_MASK AVIC_PHYSICAL_MAX_INDEX_MASK |
| 46 | +#define AVIC_VCPU_IDX_MASK AVIC_PHYSICAL_MAX_INDEX_MASK |
44 | 47 |
|
45 | 48 | #define AVIC_VM_ID_SHIFT HWEIGHT32(AVIC_PHYSICAL_MAX_INDEX_MASK)
|
46 | 49 | #define AVIC_VM_ID_MASK (GENMASK(31, AVIC_VM_ID_SHIFT) >> AVIC_VM_ID_SHIFT)
|
47 | 50 |
|
48 | 51 | #define AVIC_GATAG_TO_VMID(x) ((x >> AVIC_VM_ID_SHIFT) & AVIC_VM_ID_MASK)
|
49 |
| -#define AVIC_GATAG_TO_VCPUID(x) (x & AVIC_VCPU_ID_MASK) |
| 52 | +#define AVIC_GATAG_TO_VCPUIDX(x) (x & AVIC_VCPU_IDX_MASK) |
50 | 53 |
|
51 |
| -#define __AVIC_GATAG(vm_id, vcpu_id) ((((vm_id) & AVIC_VM_ID_MASK) << AVIC_VM_ID_SHIFT) | \ |
52 |
| - ((vcpu_id) & AVIC_VCPU_ID_MASK)) |
53 |
| -#define AVIC_GATAG(vm_id, vcpu_id) \ |
| 54 | +#define __AVIC_GATAG(vm_id, vcpu_idx) ((((vm_id) & AVIC_VM_ID_MASK) << AVIC_VM_ID_SHIFT) | \ |
| 55 | + ((vcpu_idx) & AVIC_VCPU_IDX_MASK)) |
| 56 | +#define AVIC_GATAG(vm_id, vcpu_idx) \ |
54 | 57 | ({ \
|
55 |
| - u32 ga_tag = __AVIC_GATAG(vm_id, vcpu_id); \ |
| 58 | + u32 ga_tag = __AVIC_GATAG(vm_id, vcpu_idx); \ |
56 | 59 | \
|
57 |
| - WARN_ON_ONCE(AVIC_GATAG_TO_VCPUID(ga_tag) != (vcpu_id)); \ |
| 60 | + WARN_ON_ONCE(AVIC_GATAG_TO_VCPUIDX(ga_tag) != (vcpu_idx)); \ |
58 | 61 | WARN_ON_ONCE(AVIC_GATAG_TO_VMID(ga_tag) != (vm_id)); \
|
59 | 62 | ga_tag; \
|
60 | 63 | })
|
61 | 64 |
|
62 |
| -static_assert(__AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_ID_MASK) == -1u); |
| 65 | +static_assert(__AVIC_GATAG(AVIC_VM_ID_MASK, AVIC_VCPU_IDX_MASK) == -1u); |
63 | 66 |
|
64 | 67 | static bool force_avic;
|
65 | 68 | module_param_unsafe(force_avic, bool, 0444);
|
@@ -140,16 +143,16 @@ int avic_ga_log_notifier(u32 ga_tag)
|
140 | 143 | struct kvm_svm *kvm_svm;
|
141 | 144 | struct kvm_vcpu *vcpu = NULL;
|
142 | 145 | u32 vm_id = AVIC_GATAG_TO_VMID(ga_tag);
|
143 |
| - u32 vcpu_id = AVIC_GATAG_TO_VCPUID(ga_tag); |
| 146 | + u32 vcpu_idx = AVIC_GATAG_TO_VCPUIDX(ga_tag); |
144 | 147 |
|
145 |
| - pr_debug("SVM: %s: vm_id=%#x, vcpu_id=%#x\n", __func__, vm_id, vcpu_id); |
146 |
| - trace_kvm_avic_ga_log(vm_id, vcpu_id); |
| 148 | + pr_debug("SVM: %s: vm_id=%#x, vcpu_idx=%#x\n", __func__, vm_id, vcpu_idx); |
| 149 | + trace_kvm_avic_ga_log(vm_id, vcpu_idx); |
147 | 150 |
|
148 | 151 | spin_lock_irqsave(&svm_vm_data_hash_lock, flags);
|
149 | 152 | hash_for_each_possible(svm_vm_data_hash, kvm_svm, hnode, vm_id) {
|
150 | 153 | if (kvm_svm->avic_vm_id != vm_id)
|
151 | 154 | continue;
|
152 |
| - vcpu = kvm_get_vcpu_by_id(&kvm_svm->kvm, vcpu_id); |
| 155 | + vcpu = kvm_get_vcpu(&kvm_svm->kvm, vcpu_idx); |
153 | 156 | break;
|
154 | 157 | }
|
155 | 158 | spin_unlock_irqrestore(&svm_vm_data_hash_lock, flags);
|
@@ -786,7 +789,7 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
|
786 | 789 | */
|
787 | 790 | struct amd_iommu_pi_data pi_data = {
|
788 | 791 | .ga_tag = AVIC_GATAG(to_kvm_svm(kvm)->avic_vm_id,
|
789 |
| - vcpu->vcpu_id), |
| 792 | + vcpu->vcpu_idx), |
790 | 793 | .is_guest_mode = kvm_vcpu_apicv_active(vcpu),
|
791 | 794 | .vapic_addr = avic_get_backing_page_address(to_svm(vcpu)),
|
792 | 795 | .vector = vector,
|
|
0 commit comments