Commit fb3de9f9 authored by Yi Liu's avatar Yi Liu Committed by Joerg Roedel
Browse files

iommu: Prevent pasid attach if no ops->remove_dev_pasid



driver should implement both set_dev_pasid and remove_dev_pasid op, otherwise
it is a problem how to detach pasid. In reality, it is impossible that an
iommu driver implements set_dev_pasid() but no remove_dev_pasid() op. However,
it is better to check it.

Move the group check to be the first as dev_iommu_ops() may fail when there
is no valid group. Also take the chance to remove the dev_has_iommu() check
as it is duplicated to the group check.

Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarYi Liu <yi.l.liu@intel.com>
Reviewed-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Link: https://lore.kernel.org/r/20241204122928.11987-2-yi.l.liu@intel.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 78d4f34e
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -3368,16 +3368,19 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
	/* Caller must be a probed driver on dev */
	struct iommu_group *group = dev->iommu_group;
	struct group_device *device;
	const struct iommu_ops *ops;
	int ret;

	if (!domain->ops->set_dev_pasid)
		return -EOPNOTSUPP;

	if (!group)
		return -ENODEV;

	if (!dev_has_iommu(dev) || dev_iommu_ops(dev) != domain->owner ||
	    pasid == IOMMU_NO_PASID)
	ops = dev_iommu_ops(dev);

	if (!domain->ops->set_dev_pasid ||
	    !ops->remove_dev_pasid)
		return -EOPNOTSUPP;

	if (ops != domain->owner || pasid == IOMMU_NO_PASID)
		return -EINVAL;

	mutex_lock(&group->mutex);