@@ -3644,11 +3644,12 @@ static int alloc_irq_index(u16 devid, int count)
36443644 return index ;
36453645}
36463646
3647- static int modify_irte (u16 devid , int index , union irte irte )
3647+ static int modify_irte_ga (u16 devid , int index , struct irte_ga * irte )
36483648{
36493649 struct irq_remap_table * table ;
36503650 struct amd_iommu * iommu ;
36513651 unsigned long flags ;
3652+ struct irte_ga * entry ;
36523653
36533654 iommu = amd_iommu_rlookup_table [devid ];
36543655 if (iommu == NULL )
@@ -3659,7 +3660,38 @@ static int modify_irte(u16 devid, int index, union irte irte)
36593660 return - ENOMEM ;
36603661
36613662 spin_lock_irqsave (& table -> lock , flags );
3662- table -> table [index ] = irte .val ;
3663+
3664+ entry = (struct irte_ga * )table -> table ;
3665+ entry = & entry [index ];
3666+ entry -> lo .fields_remap .valid = 0 ;
3667+ entry -> hi .val = irte -> hi .val ;
3668+ entry -> lo .val = irte -> lo .val ;
3669+ entry -> lo .fields_remap .valid = 1 ;
3670+
3671+ spin_unlock_irqrestore (& table -> lock , flags );
3672+
3673+ iommu_flush_irt (iommu , devid );
3674+ iommu_completion_wait (iommu );
3675+
3676+ return 0 ;
3677+ }
3678+
3679+ static int modify_irte (u16 devid , int index , union irte * irte )
3680+ {
3681+ struct irq_remap_table * table ;
3682+ struct amd_iommu * iommu ;
3683+ unsigned long flags ;
3684+
3685+ iommu = amd_iommu_rlookup_table [devid ];
3686+ if (iommu == NULL )
3687+ return - EINVAL ;
3688+
3689+ table = get_irq_table (devid , false);
3690+ if (!table )
3691+ return - ENOMEM ;
3692+
3693+ spin_lock_irqsave (& table -> lock , flags );
3694+ table -> table [index ] = irte -> val ;
36633695 spin_unlock_irqrestore (& table -> lock , flags );
36643696
36653697 iommu_flush_irt (iommu , devid );
@@ -3690,6 +3722,134 @@ static void free_irte(u16 devid, int index)
36903722 iommu_completion_wait (iommu );
36913723}
36923724
3725+ static void irte_prepare (void * entry ,
3726+ u32 delivery_mode , u32 dest_mode ,
3727+ u8 vector , u32 dest_apicid )
3728+ {
3729+ union irte * irte = (union irte * ) entry ;
3730+
3731+ irte -> val = 0 ;
3732+ irte -> fields .vector = vector ;
3733+ irte -> fields .int_type = delivery_mode ;
3734+ irte -> fields .destination = dest_apicid ;
3735+ irte -> fields .dm = dest_mode ;
3736+ irte -> fields .valid = 1 ;
3737+ }
3738+
3739+ static void irte_ga_prepare (void * entry ,
3740+ u32 delivery_mode , u32 dest_mode ,
3741+ u8 vector , u32 dest_apicid )
3742+ {
3743+ struct irte_ga * irte = (struct irte_ga * ) entry ;
3744+
3745+ irte -> lo .val = 0 ;
3746+ irte -> hi .val = 0 ;
3747+ irte -> lo .fields_remap .guest_mode = 0 ;
3748+ irte -> lo .fields_remap .int_type = delivery_mode ;
3749+ irte -> lo .fields_remap .dm = dest_mode ;
3750+ irte -> hi .fields .vector = vector ;
3751+ irte -> lo .fields_remap .destination = dest_apicid ;
3752+ irte -> lo .fields_remap .valid = 1 ;
3753+ }
3754+
3755+ static void irte_activate (void * entry , u16 devid , u16 index )
3756+ {
3757+ union irte * irte = (union irte * ) entry ;
3758+
3759+ irte -> fields .valid = 1 ;
3760+ modify_irte (devid , index , irte );
3761+ }
3762+
3763+ static void irte_ga_activate (void * entry , u16 devid , u16 index )
3764+ {
3765+ struct irte_ga * irte = (struct irte_ga * ) entry ;
3766+
3767+ irte -> lo .fields_remap .valid = 1 ;
3768+ modify_irte_ga (devid , index , irte );
3769+ }
3770+
3771+ static void irte_deactivate (void * entry , u16 devid , u16 index )
3772+ {
3773+ union irte * irte = (union irte * ) entry ;
3774+
3775+ irte -> fields .valid = 0 ;
3776+ modify_irte (devid , index , irte );
3777+ }
3778+
3779+ static void irte_ga_deactivate (void * entry , u16 devid , u16 index )
3780+ {
3781+ struct irte_ga * irte = (struct irte_ga * ) entry ;
3782+
3783+ irte -> lo .fields_remap .valid = 0 ;
3784+ modify_irte_ga (devid , index , irte );
3785+ }
3786+
3787+ static void irte_set_affinity (void * entry , u16 devid , u16 index ,
3788+ u8 vector , u32 dest_apicid )
3789+ {
3790+ union irte * irte = (union irte * ) entry ;
3791+
3792+ irte -> fields .vector = vector ;
3793+ irte -> fields .destination = dest_apicid ;
3794+ modify_irte (devid , index , irte );
3795+ }
3796+
3797+ static void irte_ga_set_affinity (void * entry , u16 devid , u16 index ,
3798+ u8 vector , u32 dest_apicid )
3799+ {
3800+ struct irte_ga * irte = (struct irte_ga * ) entry ;
3801+
3802+ irte -> hi .fields .vector = vector ;
3803+ irte -> lo .fields_remap .destination = dest_apicid ;
3804+ irte -> lo .fields_remap .guest_mode = 0 ;
3805+ modify_irte_ga (devid , index , irte );
3806+ }
3807+
3808+ static void irte_set_allocated (struct irq_remap_table * table , int index )
3809+ {
3810+ table -> table [index ] = IRTE_ALLOCATED ;
3811+ }
3812+
3813+ static void irte_ga_set_allocated (struct irq_remap_table * table , int index )
3814+ {
3815+ struct irte_ga * ptr = (struct irte_ga * )table -> table ;
3816+ struct irte_ga * irte = & ptr [index ];
3817+
3818+ memset (& irte -> lo .val , 0 , sizeof (u64 ));
3819+ memset (& irte -> hi .val , 0 , sizeof (u64 ));
3820+ irte -> hi .fields .vector = 0xff ;
3821+ }
3822+
3823+ static bool irte_is_allocated (struct irq_remap_table * table , int index )
3824+ {
3825+ union irte * ptr = (union irte * )table -> table ;
3826+ union irte * irte = & ptr [index ];
3827+
3828+ return irte -> val != 0 ;
3829+ }
3830+
3831+ static bool irte_ga_is_allocated (struct irq_remap_table * table , int index )
3832+ {
3833+ struct irte_ga * ptr = (struct irte_ga * )table -> table ;
3834+ struct irte_ga * irte = & ptr [index ];
3835+
3836+ return irte -> hi .fields .vector != 0 ;
3837+ }
3838+
3839+ static void irte_clear_allocated (struct irq_remap_table * table , int index )
3840+ {
3841+ table -> table [index ] = 0 ;
3842+ }
3843+
3844+ static void irte_ga_clear_allocated (struct irq_remap_table * table , int index )
3845+ {
3846+ struct irte_ga * ptr = (struct irte_ga * )table -> table ;
3847+ struct irte_ga * irte = & ptr [index ];
3848+
3849+ memset (& irte -> lo .val , 0 , sizeof (u64 ));
3850+ memset (& irte -> hi .val , 0 , sizeof (u64 ));
3851+ }
3852+
36933853static int get_devid (struct irq_alloc_info * info )
36943854{
36953855 int devid = -1 ;
@@ -3817,6 +3977,26 @@ static void irq_remapping_prepare_irte(struct amd_ir_data *data,
38173977 }
38183978}
38193979
3980+ struct amd_irte_ops irte_32_ops = {
3981+ .prepare = irte_prepare ,
3982+ .activate = irte_activate ,
3983+ .deactivate = irte_deactivate ,
3984+ .set_affinity = irte_set_affinity ,
3985+ .set_allocated = irte_set_allocated ,
3986+ .is_allocated = irte_is_allocated ,
3987+ .clear_allocated = irte_clear_allocated ,
3988+ };
3989+
3990+ struct amd_irte_ops irte_128_ops = {
3991+ .prepare = irte_ga_prepare ,
3992+ .activate = irte_ga_activate ,
3993+ .deactivate = irte_ga_deactivate ,
3994+ .set_affinity = irte_ga_set_affinity ,
3995+ .set_allocated = irte_ga_set_allocated ,
3996+ .is_allocated = irte_ga_is_allocated ,
3997+ .clear_allocated = irte_ga_clear_allocated ,
3998+ };
3999+
38204000static int irq_remapping_alloc (struct irq_domain * domain , unsigned int virq ,
38214001 unsigned int nr_irqs , void * arg )
38224002{
@@ -3922,7 +4102,7 @@ static void irq_remapping_activate(struct irq_domain *domain,
39224102 struct amd_ir_data * data = irq_data -> chip_data ;
39234103 struct irq_2_irte * irte_info = & data -> irq_2_irte ;
39244104
3925- modify_irte (irte_info -> devid , irte_info -> index , data -> irte_entry );
4105+ modify_irte (irte_info -> devid , irte_info -> index , & data -> irte_entry );
39264106}
39274107
39284108static void irq_remapping_deactivate (struct irq_domain * domain ,
@@ -3933,7 +4113,7 @@ static void irq_remapping_deactivate(struct irq_domain *domain,
39334113 union irte entry ;
39344114
39354115 entry .val = 0 ;
3936- modify_irte (irte_info -> devid , irte_info -> index , data -> irte_entry );
4116+ modify_irte (irte_info -> devid , irte_info -> index , & data -> irte_entry );
39374117}
39384118
39394119static struct irq_domain_ops amd_ir_domain_ops = {
@@ -3962,7 +4142,7 @@ static int amd_ir_set_affinity(struct irq_data *data,
39624142 */
39634143 ir_data -> irte_entry .fields .vector = cfg -> vector ;
39644144 ir_data -> irte_entry .fields .destination = cfg -> dest_apicid ;
3965- modify_irte (irte_info -> devid , irte_info -> index , ir_data -> irte_entry );
4145+ modify_irte (irte_info -> devid , irte_info -> index , & ir_data -> irte_entry );
39664146
39674147 /*
39684148 * After this point, all the interrupts will start arriving
0 commit comments