Commit b1427432 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'iommu-fixes-v6.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux

Pull iommu fix from Joerg Roedel:

 - core: skip PASID validation for devices without PASID support

* tag 'iommu-fixes-v6.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux:
  iommu: Skip PASID validation for devices without PASID capability
parents 4856ebd9 b3f6fcd8
Loading
Loading
Loading
Loading
+28 −15
Original line number Diff line number Diff line
@@ -3366,11 +3366,13 @@ static int __iommu_set_group_pasid(struct iommu_domain *domain,
	int ret;

	for_each_group_device(group, device) {
		if (device->dev->iommu->max_pasids > 0) {
			ret = domain->ops->set_dev_pasid(domain, device->dev,
							 pasid, old);
			if (ret)
				goto err_revert;
		}
	}

	return 0;

@@ -3379,16 +3381,19 @@ static int __iommu_set_group_pasid(struct iommu_domain *domain,
	for_each_group_device(group, device) {
		if (device == last_gdev)
			break;
		if (device->dev->iommu->max_pasids > 0) {
			/*
			 * If no old domain, undo the succeeded devices/pasid.
		 * Otherwise, rollback the succeeded devices/pasid to the old
		 * domain. And it is a driver bug to fail attaching with a
		 * previously good domain.
			 * Otherwise, rollback the succeeded devices/pasid to
			 * the old domain. And it is a driver bug to fail
			 * attaching with a previously good domain.
			 */
		if (!old || WARN_ON(old->ops->set_dev_pasid(old, device->dev,
			if (!old ||
			    WARN_ON(old->ops->set_dev_pasid(old, device->dev,
							    pasid, domain)))
				iommu_remove_dev_pasid(device->dev, pasid, domain);
		}
	}
	return ret;
}

@@ -3398,9 +3403,11 @@ static void __iommu_remove_group_pasid(struct iommu_group *group,
{
	struct group_device *device;

	for_each_group_device(group, device)
	for_each_group_device(group, device) {
		if (device->dev->iommu->max_pasids > 0)
			iommu_remove_dev_pasid(device->dev, pasid, domain);
	}
}

/*
 * iommu_attach_device_pasid() - Attach a domain to pasid of device
@@ -3440,7 +3447,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;
		}