@@ -3718,7 +3718,8 @@ static int alloc_irq_index(u16 devid, int count)
37183718 return index ;
37193719}
37203720
3721- static int modify_irte_ga (u16 devid , int index , struct irte_ga * irte )
3721+ static int modify_irte_ga (u16 devid , int index , struct irte_ga * irte ,
3722+ struct amd_ir_data * data )
37223723{
37233724 struct irq_remap_table * table ;
37243725 struct amd_iommu * iommu ;
@@ -3741,6 +3742,8 @@ static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte)
37413742 entry -> hi .val = irte -> hi .val ;
37423743 entry -> lo .val = irte -> lo .val ;
37433744 entry -> lo .fields_remap .valid = 1 ;
3745+ if (data )
3746+ data -> ref = entry ;
37443747
37453748 spin_unlock_irqrestore (& table -> lock , flags );
37463749
@@ -3839,7 +3842,7 @@ static void irte_ga_activate(void *entry, u16 devid, u16 index)
38393842 struct irte_ga * irte = (struct irte_ga * ) entry ;
38403843
38413844 irte -> lo .fields_remap .valid = 1 ;
3842- modify_irte_ga (devid , index , irte );
3845+ modify_irte_ga (devid , index , irte , NULL );
38433846}
38443847
38453848static void irte_deactivate (void * entry , u16 devid , u16 index )
@@ -3855,7 +3858,7 @@ static void irte_ga_deactivate(void *entry, u16 devid, u16 index)
38553858 struct irte_ga * irte = (struct irte_ga * ) entry ;
38563859
38573860 irte -> lo .fields_remap .valid = 0 ;
3858- modify_irte_ga (devid , index , irte );
3861+ modify_irte_ga (devid , index , irte , NULL );
38593862}
38603863
38613864static void irte_set_affinity (void * entry , u16 devid , u16 index ,
@@ -3876,7 +3879,7 @@ static void irte_ga_set_affinity(void *entry, u16 devid, u16 index,
38763879 irte -> hi .fields .vector = vector ;
38773880 irte -> lo .fields_remap .destination = dest_apicid ;
38783881 irte -> lo .fields_remap .guest_mode = 0 ;
3879- modify_irte_ga (devid , index , irte );
3882+ modify_irte_ga (devid , index , irte , NULL );
38803883}
38813884
38823885#define IRTE_ALLOCATED (~1U)
@@ -4211,6 +4214,62 @@ static struct irq_domain_ops amd_ir_domain_ops = {
42114214 .deactivate = irq_remapping_deactivate ,
42124215};
42134216
4217+ static int amd_ir_set_vcpu_affinity (struct irq_data * data , void * vcpu_info )
4218+ {
4219+ struct amd_iommu * iommu ;
4220+ struct amd_iommu_pi_data * pi_data = vcpu_info ;
4221+ struct vcpu_data * vcpu_pi_info = pi_data -> vcpu_data ;
4222+ struct amd_ir_data * ir_data = data -> chip_data ;
4223+ struct irte_ga * irte = (struct irte_ga * ) ir_data -> entry ;
4224+ struct irq_2_irte * irte_info = & ir_data -> irq_2_irte ;
4225+
4226+ pi_data -> ir_data = ir_data ;
4227+
4228+ /* Note:
4229+ * SVM tries to set up for VAPIC mode, but we are in
4230+ * legacy mode. So, we force legacy mode instead.
4231+ */
4232+ if (!AMD_IOMMU_GUEST_IR_VAPIC (amd_iommu_guest_ir )) {
4233+ pr_debug ("AMD-Vi: %s: Fall back to using intr legacy remap\n" ,
4234+ __func__ );
4235+ pi_data -> is_guest_mode = false;
4236+ }
4237+
4238+ iommu = amd_iommu_rlookup_table [irte_info -> devid ];
4239+ if (iommu == NULL )
4240+ return - EINVAL ;
4241+
4242+ pi_data -> prev_ga_tag = ir_data -> cached_ga_tag ;
4243+ if (pi_data -> is_guest_mode ) {
4244+ /* Setting */
4245+ irte -> hi .fields .ga_root_ptr = (pi_data -> base >> 12 );
4246+ irte -> hi .fields .vector = vcpu_pi_info -> vector ;
4247+ irte -> lo .fields_vapic .guest_mode = 1 ;
4248+ irte -> lo .fields_vapic .ga_tag = pi_data -> ga_tag ;
4249+
4250+ ir_data -> cached_ga_tag = pi_data -> ga_tag ;
4251+ } else {
4252+ /* Un-Setting */
4253+ struct irq_cfg * cfg = irqd_cfg (data );
4254+
4255+ irte -> hi .val = 0 ;
4256+ irte -> lo .val = 0 ;
4257+ irte -> hi .fields .vector = cfg -> vector ;
4258+ irte -> lo .fields_remap .guest_mode = 0 ;
4259+ irte -> lo .fields_remap .destination = cfg -> dest_apicid ;
4260+ irte -> lo .fields_remap .int_type = apic -> irq_delivery_mode ;
4261+ irte -> lo .fields_remap .dm = apic -> irq_dest_mode ;
4262+
4263+ /*
4264+ * This communicates the ga_tag back to the caller
4265+ * so that it can do all the necessary clean up.
4266+ */
4267+ ir_data -> cached_ga_tag = 0 ;
4268+ }
4269+
4270+ return modify_irte_ga (irte_info -> devid , irte_info -> index , irte , ir_data );
4271+ }
4272+
42144273static int amd_ir_set_affinity (struct irq_data * data ,
42154274 const struct cpumask * mask , bool force )
42164275{
@@ -4255,6 +4314,7 @@ static void ir_compose_msi_msg(struct irq_data *irq_data, struct msi_msg *msg)
42554314static struct irq_chip amd_ir_chip = {
42564315 .irq_ack = ir_ack_apic_edge ,
42574316 .irq_set_affinity = amd_ir_set_affinity ,
4317+ .irq_set_vcpu_affinity = amd_ir_set_vcpu_affinity ,
42584318 .irq_compose_msi_msg = ir_compose_msi_msg ,
42594319};
42604320
0 commit comments