]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iommu/amd: KVM: SVM: Add IRTE metadata to affined vCPU's list if AVIC is inhibited
authorSean Christopherson <seanjc@google.com>
Wed, 11 Jun 2025 22:45:46 +0000 (15:45 -0700)
committerSean Christopherson <seanjc@google.com>
Mon, 23 Jun 2025 16:50:40 +0000 (09:50 -0700)
If an IRQ can be posted to a vCPU, but AVIC is currently inhibited on the
vCPU, go through the dance of "affining" the IRTE to the vCPU, but leave
the actual IRTE in remapped mode.  KVM already handles the case where AVIC
is inhibited => uninhibited with posted IRQs (see avic_set_pi_irte_mode()),
but doesn't handle the scenario where a postable IRQ comes along while AVIC
is inhibited.

Link: https://lore.kernel.org/r/20250611224604.313496-45-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/svm/avic.c
drivers/iommu/amd/iommu.c

index 35c5fb831c289f4ad01fbe7481d45341182cd0e8..cb6317fcaddf77ddbb4f50d5c0d9a3bbe010100c 100644 (file)
@@ -781,21 +781,17 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
         */
        svm_ir_list_del(irqfd);
 
-       /**
-        * Here, we setup with legacy mode in the following cases:
-        * 1. When cannot target interrupt to a specific vcpu.
-        * 2. Unsetting posted interrupt.
-        * 3. APIC virtualization is disabled for the vcpu.
-        * 4. IRQ has incompatible delivery mode (SMI, INIT, etc)
-        */
-       if (vcpu && kvm_vcpu_apicv_active(vcpu)) {
+       if (vcpu) {
                /*
-                * Try to enable guest_mode in IRTE.
+                * Try to enable guest_mode in IRTE, unless AVIC is inhibited,
+                * in which case configure the IRTE for legacy mode, but track
+                * the IRTE metadata so that it can be converted to guest mode
+                * if AVIC is enabled/uninhibited in the future.
                 */
                struct amd_iommu_pi_data pi_data = {
                        .ga_tag = AVIC_GATAG(to_kvm_svm(kvm)->avic_vm_id,
                                             vcpu->vcpu_id),
-                       .is_guest_mode = true,
+                       .is_guest_mode = kvm_vcpu_apicv_active(vcpu),
                        .vapic_addr = avic_get_backing_page_address(to_svm(vcpu)),
                        .vector = vector,
                };
index 6352930ad0115000fb498434a219d2c2c0ea332a..6149aece0eacf808dde752a257532b8f6eade7b3 100644 (file)
@@ -3939,7 +3939,10 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *info)
                ir_data->ga_root_ptr = (pi_data->vapic_addr >> 12);
                ir_data->ga_vector = pi_data->vector;
                ir_data->ga_tag = pi_data->ga_tag;
-               ret = amd_iommu_activate_guest_mode(ir_data, pi_data->cpu);
+               if (pi_data->is_guest_mode)
+                       ret = amd_iommu_activate_guest_mode(ir_data, pi_data->cpu);
+               else
+                       ret = amd_iommu_deactivate_guest_mode(ir_data);
        } else {
                ret = amd_iommu_deactivate_guest_mode(ir_data);
        }