[PATCH v5 06/27] iommu/arm-smmu-v3: Consolidate clearing a CD table entry

Moritz Fischer moritzf at google.com
Sat Mar 16 11:15:44 PDT 2024


On Mon, Mar 04, 2024 at 07:43:54PM -0400, Jason Gunthorpe wrote:
> A cleared entry is all 0's. Make arm_smmu_clear_cd() do this sequence.

> If we are clearing an entry and for some reason it is not already
> allocated in the CD table then something has gone wrong.

> Tested-by: Nicolin Chen <nicolinc at nvidia.com>
> Signed-off-by: Jason Gunthorpe <jgg at nvidia.com>
> ---
>   .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   |  2 +-
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 20 ++++++++++++++-----
>   drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  2 ++
>   3 files changed, 18 insertions(+), 6 deletions(-)

> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c  
> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> index 347c2fdd865c1a..bb9bb6fd7914ce 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
> @@ -558,7 +558,7 @@ void arm_smmu_sva_remove_dev_pasid(struct  
> iommu_domain *domain,

>   	mutex_lock(&sva_lock);

> -	arm_smmu_write_ctx_desc(master, id, NULL);
> +	arm_smmu_clear_cd(master, id);

>   	list_for_each_entry(t, &master->bonds, list) {
>   		if (t->mm == mm) {
> 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 237fd6d92c880b..3fb4a1523d1d3f 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -1303,6 +1303,19 @@ static void arm_smmu_write_cd_entry(struct  
> arm_smmu_master *master, int ssid,
>   	arm_smmu_write_entry(&cd_writer.writer, cdptr->data, target->data);
>   }

> +void arm_smmu_clear_cd(struct arm_smmu_master *master, ioasid_t ssid)
> +{
> +	struct arm_smmu_cd target = {};
> +	struct arm_smmu_cd *cdptr;
> +
> +	if (!master->cd_table.cdtab)
> +		return;
> +	cdptr = arm_smmu_get_cd_ptr(master, ssid);
> +	if (WARN_ON(!cdptr))
> +		return;
> +	arm_smmu_write_cd_entry(master, ssid, cdptr, &target);
> +}
> +
>   int arm_smmu_write_ctx_desc(struct arm_smmu_master *master, int ssid,
>   			    struct arm_smmu_ctx_desc *cd)
>   {
> @@ -2702,9 +2715,7 @@ static int arm_smmu_attach_dev(struct iommu_domain  
> *domain, struct device *dev)
>   	case ARM_SMMU_DOMAIN_S2:
>   		arm_smmu_make_s2_domain_ste(&target, master, smmu_domain);
>   		arm_smmu_install_ste_for_dev(master, &target);
> -		if (master->cd_table.cdtab)
> -			arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID,
> -						      NULL);
> +		arm_smmu_clear_cd(master, IOMMU_NO_PASID);
>   		break;
>   	}

> @@ -2752,8 +2763,7 @@ static int arm_smmu_attach_dev_ste(struct device  
> *dev,
>   	 * arm_smmu_domain->devices to avoid races updating the same context
>   	 * descriptor from arm_smmu_share_asid().
>   	 */
> -	if (master->cd_table.cdtab)
> -		arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, NULL);
> +	arm_smmu_clear_cd(master, IOMMU_NO_PASID);
>   	return 0;
>   }

> 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 7078ed569fd4d3..87a7b57f566fbc 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -749,6 +749,8 @@ extern struct xarray arm_smmu_asid_xa;
>   extern struct mutex arm_smmu_asid_lock;
>   extern struct arm_smmu_ctx_desc quiet_cd;

> +void arm_smmu_clear_cd(struct arm_smmu_master *master, ioasid_t ssid);
> +
>   int arm_smmu_write_ctx_desc(struct arm_smmu_master *smmu_master, int  
> ssid,
>   			    struct arm_smmu_ctx_desc *cd);
>   void arm_smmu_tlb_inv_asid(struct arm_smmu_device *smmu, u16 asid);
> --
> 2.43.2


Reviewed-by: Moritz Fischer <moritzf at google.com>



More information about the linux-arm-kernel mailing list