[PATCH v4 18/24] iommu/arm-smmu-v3: Introduce master->ats_broken flag

Jason Gunthorpe jgg at nvidia.com
Tue May 19 05:06:58 PDT 2026


On Mon, May 18, 2026 at 08:39:01PM -0700, Nicolin Chen wrote:

> 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 cde2ff2dcc49b..638956e2535b4 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2429,6 +2429,10 @@ static int arm_smmu_atc_inv_master(struct arm_smmu_master *master,
>  	struct arm_smmu_cmd cmd;
>  	struct arm_smmu_cmdq_batch cmds;
>  
> +	/* Do not issue ATC_INV that will definitely time out */
> +	if (READ_ONCE(master->ats_broken))
> +		return 0;
> +
>  	cmd = arm_smmu_make_cmd_atc_inv_all(0, IOMMU_NO_PASID);
>  	arm_smmu_cmdq_batch_init_cmd(master->smmu, &cmds, &cmd);
>  	for (i = 0; i < master->num_streams; i++)
> @@ -2651,12 +2655,18 @@ static void __arm_smmu_domain_inv_range(struct arm_smmu_invs *invs,
>  						       cur->id));
>  			break;
>  		case INV_TYPE_ATS:
> +			/* Do not issue ATC_INV that will definitely time out */
> +			if (READ_ONCE(cur->master->ats_broken))
> +				break;

Yuk, this should be a bool in the invs list, not the master.

If the flow is to have the core code always attach a blocked domain before
reset_done then the invs list will naturally fix itself.

> @@ -3007,6 +3027,14 @@ static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
>  	if (!(fwspec->flags & IOMMU_FWSPEC_PCI_RC_ATS))
>  		return false;
>  
> +	/*
> +	 * Do not enable ATS if master->ats_broken is set. The PCI device should
> +	 * go through a recovery (reset) that shall notify the SMMUv3 driver via
> +	 * a reset_device_done callback.
> +	 */

Should just fail attach of paging domains at this point, the core code
should arguably be preventing races like this. Attaching a paging
domain in a broken way is going to create more problems.

Jason



More information about the linux-arm-kernel mailing list