diff options
| author | Jason Gunthorpe <jgg@nvidia.com> | 2024-02-26 13:07:21 -0400 | 
|---|---|---|
| committer | Will Deacon <will@kernel.org> | 2024-02-29 15:12:22 +0000 | 
| commit | 1b50017d39f650d78a0066734d6fe05920a8c9e8 (patch) | |
| tree | 913f84b3833889451c9a83297b20702d5b111a05 | |
| parent | d550ddc5b789f258cb5ce3bfe74af6d5383589b5 (diff) | |
iommu/arm-smmu-v3: Remove arm_smmu_master->domain
Introducing global statics which are of type struct iommu_domain, not
struct arm_smmu_domain makes it difficult to retain
arm_smmu_master->domain, as it can no longer point to an IDENTITY or
BLOCKED domain.
The only place that uses the value is arm_smmu_detach_dev(). Change things
to work like other drivers and call iommu_get_domain_for_dev() to obtain
the current domain.
The master->domain is subtly protecting the master->domain_head against
being unused as only PAGING domains will set master->domain and only
paging domains use the master->domain_head. To make it simple keep the
master->domain_head initialized so that the list_del() logic just does
nothing for attached non-PAGING domains.
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Moritz Fischer <moritzf@google.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Mostafa Saleh <smostafa@google.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/10-v6-96275f25c39d+2d4-smmuv3_newapi_p1_jgg@nvidia.com
Signed-off-by: Will Deacon <will@kernel.org>
| -rw-r--r-- | drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 26 | ||||
| -rw-r--r-- | drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 | 
2 files changed, 10 insertions, 17 deletions
| diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 9d36ddecf2ad..19a7f0468149 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -2507,19 +2507,20 @@ static void arm_smmu_disable_pasid(struct arm_smmu_master *master)  static void arm_smmu_detach_dev(struct arm_smmu_master *master)  { +	struct iommu_domain *domain = iommu_get_domain_for_dev(master->dev); +	struct arm_smmu_domain *smmu_domain;  	unsigned long flags; -	struct arm_smmu_domain *smmu_domain = master->domain; -	if (!smmu_domain) +	if (!domain)  		return; +	smmu_domain = to_smmu_domain(domain);  	arm_smmu_disable_ats(master, smmu_domain);  	spin_lock_irqsave(&smmu_domain->devices_lock, flags); -	list_del(&master->domain_head); +	list_del_init(&master->domain_head);  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags); -	master->domain = NULL;  	master->ats_enabled = false;  } @@ -2573,8 +2574,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)  	arm_smmu_detach_dev(master); -	master->domain = smmu_domain; -  	/*  	 * The SMMU does not support enabling ATS with bypass. When the STE is  	 * in bypass (STE.Config[2:0] == 0b100), ATS Translation Requests and @@ -2593,10 +2592,8 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)  	case ARM_SMMU_DOMAIN_S1:  		if (!master->cd_table.cdtab) {  			ret = arm_smmu_alloc_cd_tables(master); -			if (ret) { -				master->domain = NULL; +			if (ret)  				goto out_list_del; -			}  		} else {  			/*  			 * arm_smmu_write_ctx_desc() relies on the entry being @@ -2604,17 +2601,13 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)  			 */  			ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,  						      NULL); -			if (ret) { -				master->domain = NULL; +			if (ret)  				goto out_list_del; -			}  		}  		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd); -		if (ret) { -			master->domain = NULL; +		if (ret)  			goto out_list_del; -		}  		arm_smmu_make_cdtable_ste(&target, master);  		arm_smmu_install_ste_for_dev(master, &target); @@ -2640,7 +2633,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)  out_list_del:  	spin_lock_irqsave(&smmu_domain->devices_lock, flags); -	list_del(&master->domain_head); +	list_del_init(&master->domain_head);  	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);  out_unlock: @@ -2841,6 +2834,7 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)  	master->dev = dev;  	master->smmu = smmu;  	INIT_LIST_HEAD(&master->bonds); +	INIT_LIST_HEAD(&master->domain_head);  	dev_iommu_priv_set(dev, master);  	ret = arm_smmu_insert_master(smmu, master); diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index eb669121f195..6b63ea7dae72 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -695,7 +695,6 @@ struct arm_smmu_stream {  struct arm_smmu_master {  	struct arm_smmu_device		*smmu;  	struct device			*dev; -	struct arm_smmu_domain		*domain;  	struct list_head		domain_head;  	struct arm_smmu_stream		*streams;  	/* Locked by the iommu core using the group mutex */ | 
