[PATCH v5 06/15] iommu/arm-smmu-v3: Allocate IOPF queue without FEAT_SVA

Jason Gunthorpe jgg at nvidia.com
Wed Sep 23 11:37:05 PDT 2026


> arm_smmu_init_queues() allocates the IOPF queue only for FEAT_SVA together
> with FEAT_STALLS. This queue has no SVA dependency, and FEAT_STALLS alone
> can produce events that need IOPF.

Until iommufd there was no other way to create faults in the first
place. Doesn't matter if the HW supports it.

> 
> On HW with FEAT_STALLS but no FEAT_SVA, a master with the "dma-can-stall"
> device-tree property has master->stall_enabled set at probe. Then also with
> CONFIG_ARM_SMMU_V3_SVA=y, arm_smmu_enable_iopf() sees stall_enabled, calls
> iopf_queue_add_device(NULL, ...) at fault-handling domain attach, which can
> oops on mutex_lock(&queue->lock).

Yeah the guards got mismatched. There should have been a

arm_smmu_iopf_enabled(smmu)
	if (!IS_ENABLED(CONFIG_ARM_SMMU_V3_SVA)) return false
        if (!(smmu->features & ARM_SMMU_FEAT_SVA)) return false

And that is used everywhere. The fact one place used the feat and the
other used the CONFIG is the cause of this crash.

> [ ... 32 lines skipped ... ]
> @@ -3215,9 +3215,6 @@ static int arm_smmu_enable_iopf(struct arm_smmu_master *master,
>  
>  	iommu_group_mutex_assert(master->dev);
>  
> -	if (!IS_ENABLED(CONFIG_ARM_SMMU_V3_SVA))
> -		return -EOPNOTSUPP;
> -
>  	/*
>  	 * Drivers for devices supporting PRI or stall require iopf others have
>  	 * device-specific fault handlers and don't need IOPF, so this is not a
> @@ -3249,9 +3246,6 @@ static void arm_smmu_disable_iopf(struct arm_smmu_master *master,
>  {
>  	iommu_group_mutex_assert(master->dev);
>  
> -	if (!IS_ENABLED(CONFIG_ARM_SMMU_V3_SVA))
> -		return;
> -
>  	if (!master_domain || !master_domain->using_iopf)
>  		return;
>

I think this is fine

> @@ -4667,8 +4661,7 @@ static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
>  	if (ret)
>  		return ret;
>  
> -	if ((smmu->features & ARM_SMMU_FEAT_SVA) &&
> -	    (smmu->features & ARM_SMMU_FEAT_STALLS)) {
> +	if (smmu->features & ARM_SMMU_FEAT_STALLS) {
>  		smmu->evtq.iopf = iopf_queue_alloc(dev_name(smmu->dev));
>  		if (!smmu->evtq.iopf)
>  			return -ENOMEM;

But here it would still be nice to support the non-SVA optimization..

I'd change the kconfig to move the select IOMMU_IOPF down to the
iommufd and SVA blocks

Then guard this with an IS_ENABLED(CONFIG_IOMMU_IOPF)

That way you can choose to compile out IOPF if you don't want to use
any SMMU features that rely on it.

-- 
Jason



More information about the linux-arm-kernel mailing list