@@ -4036,19 +4036,21 @@ static int intel_iommu_iotlb_sync_map(struct iommu_domain *domain,
4036
4036
return 0 ;
4037
4037
}
4038
4038
4039
- static void intel_iommu_remove_dev_pasid (struct device * dev , ioasid_t pasid ,
4040
- struct iommu_domain * domain )
4039
+ void domain_remove_dev_pasid (struct iommu_domain * domain ,
4040
+ struct device * dev , ioasid_t pasid )
4041
4041
{
4042
4042
struct device_domain_info * info = dev_iommu_priv_get (dev );
4043
4043
struct dev_pasid_info * curr , * dev_pasid = NULL ;
4044
4044
struct intel_iommu * iommu = info -> iommu ;
4045
4045
struct dmar_domain * dmar_domain ;
4046
4046
unsigned long flags ;
4047
4047
4048
- if (domain -> type == IOMMU_DOMAIN_IDENTITY ) {
4049
- intel_pasid_tear_down_entry (iommu , dev , pasid , false);
4048
+ if (!domain )
4049
+ return ;
4050
+
4051
+ /* Identity domain has no meta data for pasid. */
4052
+ if (domain -> type == IOMMU_DOMAIN_IDENTITY )
4050
4053
return ;
4051
- }
4052
4054
4053
4055
dmar_domain = to_dmar_domain (domain );
4054
4056
spin_lock_irqsave (& dmar_domain -> lock , flags );
@@ -4066,7 +4068,52 @@ static void intel_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
4066
4068
domain_detach_iommu (dmar_domain , iommu );
4067
4069
intel_iommu_debugfs_remove_dev_pasid (dev_pasid );
4068
4070
kfree (dev_pasid );
4069
- intel_pasid_tear_down_entry (iommu , dev , pasid , false);
4071
+ }
4072
+
4073
+ static void intel_iommu_remove_dev_pasid (struct device * dev , ioasid_t pasid ,
4074
+ struct iommu_domain * domain )
4075
+ {
4076
+ struct device_domain_info * info = dev_iommu_priv_get (dev );
4077
+
4078
+ intel_pasid_tear_down_entry (info -> iommu , dev , pasid , false);
4079
+ domain_remove_dev_pasid (domain , dev , pasid );
4080
+ }
4081
+
4082
+ struct dev_pasid_info *
4083
+ domain_add_dev_pasid (struct iommu_domain * domain ,
4084
+ struct device * dev , ioasid_t pasid )
4085
+ {
4086
+ struct device_domain_info * info = dev_iommu_priv_get (dev );
4087
+ struct dmar_domain * dmar_domain = to_dmar_domain (domain );
4088
+ struct intel_iommu * iommu = info -> iommu ;
4089
+ struct dev_pasid_info * dev_pasid ;
4090
+ unsigned long flags ;
4091
+ int ret ;
4092
+
4093
+ dev_pasid = kzalloc (sizeof (* dev_pasid ), GFP_KERNEL );
4094
+ if (!dev_pasid )
4095
+ return ERR_PTR (- ENOMEM );
4096
+
4097
+ ret = domain_attach_iommu (dmar_domain , iommu );
4098
+ if (ret )
4099
+ goto out_free ;
4100
+
4101
+ ret = cache_tag_assign_domain (dmar_domain , dev , pasid );
4102
+ if (ret )
4103
+ goto out_detach_iommu ;
4104
+
4105
+ dev_pasid -> dev = dev ;
4106
+ dev_pasid -> pasid = pasid ;
4107
+ spin_lock_irqsave (& dmar_domain -> lock , flags );
4108
+ list_add (& dev_pasid -> link_domain , & dmar_domain -> dev_pasids );
4109
+ spin_unlock_irqrestore (& dmar_domain -> lock , flags );
4110
+
4111
+ return dev_pasid ;
4112
+ out_detach_iommu :
4113
+ domain_detach_iommu (dmar_domain , iommu );
4114
+ out_free :
4115
+ kfree (dev_pasid );
4116
+ return ERR_PTR (ret );
4070
4117
}
4071
4118
4072
4119
static int intel_iommu_set_dev_pasid (struct iommu_domain * domain ,
@@ -4077,7 +4124,6 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
4077
4124
struct dmar_domain * dmar_domain = to_dmar_domain (domain );
4078
4125
struct intel_iommu * iommu = info -> iommu ;
4079
4126
struct dev_pasid_info * dev_pasid ;
4080
- unsigned long flags ;
4081
4127
int ret ;
4082
4128
4083
4129
if (!pasid_supported (iommu ) || dev_is_real_dma_subdevice (dev ))
@@ -4093,17 +4139,9 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
4093
4139
if (ret )
4094
4140
return ret ;
4095
4141
4096
- dev_pasid = kzalloc (sizeof (* dev_pasid ), GFP_KERNEL );
4097
- if (!dev_pasid )
4098
- return - ENOMEM ;
4099
-
4100
- ret = domain_attach_iommu (dmar_domain , iommu );
4101
- if (ret )
4102
- goto out_free ;
4103
-
4104
- ret = cache_tag_assign_domain (dmar_domain , dev , pasid );
4105
- if (ret )
4106
- goto out_detach_iommu ;
4142
+ dev_pasid = domain_add_dev_pasid (domain , dev , pasid );
4143
+ if (IS_ERR (dev_pasid ))
4144
+ return PTR_ERR (dev_pasid );
4107
4145
4108
4146
if (dmar_domain -> use_first_level )
4109
4147
ret = domain_setup_first_level (iommu , dmar_domain ,
@@ -4112,24 +4150,17 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
4112
4150
ret = intel_pasid_setup_second_level (iommu , dmar_domain ,
4113
4151
dev , pasid );
4114
4152
if (ret )
4115
- goto out_unassign_tag ;
4153
+ goto out_remove_dev_pasid ;
4116
4154
4117
- dev_pasid -> dev = dev ;
4118
- dev_pasid -> pasid = pasid ;
4119
- spin_lock_irqsave (& dmar_domain -> lock , flags );
4120
- list_add (& dev_pasid -> link_domain , & dmar_domain -> dev_pasids );
4121
- spin_unlock_irqrestore (& dmar_domain -> lock , flags );
4155
+ domain_remove_dev_pasid (old , dev , pasid );
4122
4156
4123
4157
if (domain -> type & __IOMMU_DOMAIN_PAGING )
4124
4158
intel_iommu_debugfs_create_dev_pasid (dev_pasid );
4125
4159
4126
4160
return 0 ;
4127
- out_unassign_tag :
4128
- cache_tag_unassign_domain (dmar_domain , dev , pasid );
4129
- out_detach_iommu :
4130
- domain_detach_iommu (dmar_domain , iommu );
4131
- out_free :
4132
- kfree (dev_pasid );
4161
+
4162
+ out_remove_dev_pasid :
4163
+ domain_remove_dev_pasid (domain , dev , pasid );
4133
4164
return ret ;
4134
4165
}
4135
4166
0 commit comments