diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index e606d250d1d5..2a19f5640c6f 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -3514,9 +3514,11 @@ static int __iommu_set_group_pasid(struct iommu_domain *domain, int ret; for_each_group_device(group, device) { - ret = domain->ops->set_dev_pasid(domain, device->dev, pasid); - if (ret) - goto err_revert; + if (device->dev->iommu->max_pasids > 0) { + ret = domain->ops->set_dev_pasid(domain, device->dev, pasid); + if (ret) + goto err_revert; + } } return 0; @@ -3528,7 +3530,9 @@ err_revert: if (device == last_gdev) break; - ops->remove_dev_pasid(device->dev, pasid); + + if (device->dev->iommu->max_pasids > 0) + ops->remove_dev_pasid(device->dev, pasid); } return ret; } @@ -3540,8 +3544,10 @@ static void __iommu_remove_group_pasid(struct iommu_group *group, const struct iommu_ops *ops; for_each_group_device(group, device) { - ops = dev_iommu_ops(device->dev); - ops->remove_dev_pasid(device->dev, pasid); + if (device->dev->iommu->max_pasids > 0) { + ops = dev_iommu_ops(device->dev); + ops->remove_dev_pasid(device->dev, pasid); + } } } @@ -3574,7 +3580,13 @@ int iommu_attach_device_pasid(struct iommu_domain *domain, mutex_lock(&group->mutex); for_each_group_device(group, device) { - if (pasid >= device->dev->iommu->max_pasids) { + /* + * Skip PASID validation for devices without PASID support + * (max_pasids = 0). These devices cannot issue transactions + * with PASID, so they don't affect group's PASID usage. + */ + if ((device->dev->iommu->max_pasids > 0) && + (pasid >= device->dev->iommu->max_pasids)) { ret = -EINVAL; goto out_unlock; }