@@ -844,11 +844,10 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
844
844
unsigned int host_irq , uint32_t guest_irq ,
845
845
struct kvm_kernel_irq_routing_entry * new )
846
846
{
847
- struct kvm_kernel_irq_routing_entry * e ;
848
- struct kvm_irq_routing_table * irq_rt ;
849
847
bool enable_remapped_mode = true;
850
- bool set = !!new ;
851
- int idx , ret = 0 ;
848
+ struct vcpu_data vcpu_info ;
849
+ struct vcpu_svm * svm = NULL ;
850
+ int ret = 0 ;
852
851
853
852
if (!kvm_arch_has_assigned_device (kvm ) || !kvm_arch_has_irq_bypass ())
854
853
return 0 ;
@@ -860,80 +859,60 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm,
860
859
svm_ir_list_del (irqfd );
861
860
862
861
pr_debug ("SVM: %s: host_irq=%#x, guest_irq=%#x, set=%#x\n" ,
863
- __func__ , host_irq , guest_irq , set );
864
-
865
- idx = srcu_read_lock (& kvm -> irq_srcu );
866
- irq_rt = srcu_dereference (kvm -> irq_routing , & kvm -> irq_srcu );
867
-
868
- if (guest_irq >= irq_rt -> nr_rt_entries ||
869
- hlist_empty (& irq_rt -> map [guest_irq ])) {
870
- pr_warn_once ("no route for guest_irq %u/%u (broken user space?)\n" ,
871
- guest_irq , irq_rt -> nr_rt_entries );
872
- goto out ;
873
- }
874
-
875
- hlist_for_each_entry (e , & irq_rt -> map [guest_irq ], link ) {
876
- struct vcpu_data vcpu_info ;
877
- struct vcpu_svm * svm = NULL ;
862
+ __func__ , host_irq , guest_irq , !!new );
863
+
864
+ /**
865
+ * Here, we setup with legacy mode in the following cases:
866
+ * 1. When cannot target interrupt to a specific vcpu.
867
+ * 2. Unsetting posted interrupt.
868
+ * 3. APIC virtualization is disabled for the vcpu.
869
+ * 4. IRQ has incompatible delivery mode (SMI, INIT, etc)
870
+ */
871
+ if (new && new -> type == KVM_IRQ_ROUTING_MSI &&
872
+ !get_pi_vcpu_info (kvm , new , & vcpu_info , & svm ) &&
873
+ kvm_vcpu_apicv_active (& svm -> vcpu )) {
874
+ struct amd_iommu_pi_data pi ;
878
875
879
- if (e -> type != KVM_IRQ_ROUTING_MSI )
880
- continue ;
876
+ enable_remapped_mode = false;
881
877
882
- WARN_ON_ONCE (new && memcmp (e , new , sizeof (* new )));
878
+ /*
879
+ * Try to enable guest_mode in IRTE. Note, the address
880
+ * of the vCPU's AVIC backing page is passed to the
881
+ * IOMMU via vcpu_info->pi_desc_addr.
882
+ */
883
+ pi .ga_tag = AVIC_GATAG (to_kvm_svm (kvm )-> avic_vm_id ,
884
+ svm -> vcpu .vcpu_id );
885
+ pi .is_guest_mode = true;
886
+ pi .vcpu_data = & vcpu_info ;
887
+ ret = irq_set_vcpu_affinity (host_irq , & pi );
883
888
884
889
/**
885
- * Here, we setup with legacy mode in the following cases:
886
- * 1. When cannot target interrupt to a specific vcpu.
887
- * 2. Unsetting posted interrupt.
888
- * 3. APIC virtualization is disabled for the vcpu.
889
- * 4. IRQ has incompatible delivery mode (SMI, INIT, etc)
890
+ * Here, we successfully setting up vcpu affinity in
891
+ * IOMMU guest mode. Now, we need to store the posted
892
+ * interrupt information in a per-vcpu ir_list so that
893
+ * we can reference to them directly when we update vcpu
894
+ * scheduling information in IOMMU irte.
890
895
*/
891
- if (!get_pi_vcpu_info (kvm , e , & vcpu_info , & svm ) && set &&
892
- kvm_vcpu_apicv_active (& svm -> vcpu )) {
893
- struct amd_iommu_pi_data pi ;
894
-
895
- enable_remapped_mode = false;
896
-
897
- /*
898
- * Try to enable guest_mode in IRTE. Note, the address
899
- * of the vCPU's AVIC backing page is passed to the
900
- * IOMMU via vcpu_info->pi_desc_addr.
901
- */
902
- pi .ga_tag = AVIC_GATAG (to_kvm_svm (kvm )-> avic_vm_id ,
903
- svm -> vcpu .vcpu_id );
904
- pi .is_guest_mode = true;
905
- pi .vcpu_data = & vcpu_info ;
906
- ret = irq_set_vcpu_affinity (host_irq , & pi );
907
-
908
- /**
909
- * Here, we successfully setting up vcpu affinity in
910
- * IOMMU guest mode. Now, we need to store the posted
911
- * interrupt information in a per-vcpu ir_list so that
912
- * we can reference to them directly when we update vcpu
913
- * scheduling information in IOMMU irte.
914
- */
915
- if (!ret && pi .is_guest_mode )
916
- svm_ir_list_add (svm , irqfd , & pi );
917
- }
896
+ if (!ret )
897
+ ret = svm_ir_list_add (svm , irqfd , & pi );
898
+ }
918
899
919
- if (!ret && svm ) {
920
- trace_kvm_pi_irte_update (host_irq , svm -> vcpu .vcpu_id ,
921
- e -> gsi , vcpu_info .vector ,
922
- vcpu_info .pi_desc_addr , set );
923
- }
900
+ if (!ret && svm ) {
901
+ trace_kvm_pi_irte_update (host_irq , svm -> vcpu .vcpu_id ,
902
+ guest_irq , vcpu_info .vector ,
903
+ vcpu_info .pi_desc_addr , !! new );
904
+ }
924
905
925
- if (ret < 0 ) {
926
- pr_err ("%s: failed to update PI IRTE\n" , __func__ );
927
- goto out ;
928
- }
906
+ if (ret < 0 ) {
907
+ pr_err ("%s: failed to update PI IRTE\n" , __func__ );
908
+ goto out ;
929
909
}
930
910
931
911
if (enable_remapped_mode )
932
912
ret = irq_set_vcpu_affinity (host_irq , NULL );
933
913
else
934
914
ret = 0 ;
935
915
out :
936
- srcu_read_unlock (& kvm -> irq_srcu , idx );
937
916
return ret ;
938
917
}
939
918
0 commit comments