summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorSean Christopherson <seanjc@google.com>2025-06-11 15:45:40 -0700
committerSean Christopherson <seanjc@google.com>2025-06-23 09:50:35 -0700
commit71d6b3b8e69d8a212c53df1150e559b101d6768b (patch)
treedda2b6a27a676cd4cfdf5f5c4befead5110a5e8c /arch
parentcc8b13105eac969bb721c52cf95fd35818b5c54c (diff)
KVM: SVM: Revert IRTE to legacy mode if IOMMU doesn't provide IR metadata
Revert the IRTE back to remapping mode if the AMD IOMMU driver mucks up and doesn't provide the necessary metadata. Returning an error up the stack without actually handling the error is useless and confusing. Link: https://lore.kernel.org/r/20250611224604.313496-39-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/svm/avic.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index 21a822d64867..031f374a0b41 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -770,16 +770,13 @@ static void svm_ir_list_del(struct kvm_kernel_irqfd *irqfd)
spin_unlock_irqrestore(&to_svm(vcpu)->ir_list_lock, flags);
}
-static int svm_ir_list_add(struct vcpu_svm *svm,
- struct kvm_kernel_irqfd *irqfd,
- struct amd_iommu_pi_data *pi)
+static void svm_ir_list_add(struct vcpu_svm *svm,
+ struct kvm_kernel_irqfd *irqfd,
+ struct amd_iommu_pi_data *pi)
{
unsigned long flags;
u64 entry;
- if (WARN_ON_ONCE(!pi->ir_data))
- return -EINVAL;
-
irqfd->irq_bypass_data = pi->ir_data;
spin_lock_irqsave(&svm->ir_list_lock, flags);
@@ -797,7 +794,6 @@ static int svm_ir_list_add(struct vcpu_svm *svm,
list_add(&irqfd->vcpu_list, &svm->ir_list);
spin_unlock_irqrestore(&svm->ir_list_lock, flags);
- return 0;
}
int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
@@ -834,6 +830,16 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
if (ret)
return ret;
+ /*
+ * Revert to legacy mode if the IOMMU didn't provide metadata
+ * for the IRTE, which KVM needs to keep the IRTE up-to-date,
+ * e.g. if the vCPU is migrated or AVIC is disabled.
+ */
+ if (WARN_ON_ONCE(!pi_data.ir_data)) {
+ irq_set_vcpu_affinity(host_irq, NULL);
+ return -EIO;
+ }
+
/**
* Here, we successfully setting up vcpu affinity in
* IOMMU guest mode. Now, we need to store the posted
@@ -841,7 +847,8 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
* we can reference to them directly when we update vcpu
* scheduling information in IOMMU irte.
*/
- return svm_ir_list_add(to_svm(vcpu), irqfd, &pi_data);
+ svm_ir_list_add(to_svm(vcpu), irqfd, &pi_data);
+ return 0;
}
return irq_set_vcpu_affinity(host_irq, NULL);
}