summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi Liu <yi.l.liu@intel.com>2024-12-04 04:29:24 -0800
committerJoerg Roedel <jroedel@suse.de>2024-12-18 09:39:35 +0100
commitb18301b9156a0d8a0094fcd16a1b98816539eab0 (patch)
tree2c7b43966229ee4dde4fc19cce501b042b60a9c1
parent1fbf73425f5169e2d183b2ca67bfe2f1019d11c0 (diff)
iommu: Detaching pasid by attaching to the blocked_domain
The iommu drivers are on the way to detach pasid by attaching to the blocked domain. However, this cannot be done in one shot. During the transition, iommu core would select between the remove_dev_pasid op and the blocked domain. Suggested-by: Kevin Tian <kevin.tian@intel.com> Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Yi Liu <yi.l.liu@intel.com> Link: https://lore.kernel.org/r/20241204122928.11987-4-yi.l.liu@intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r--drivers/iommu/iommu.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 2ff4fa60a86a..2064dc8bb8b5 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -3316,8 +3316,18 @@ static void iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid,
struct iommu_domain *domain)
{
const struct iommu_ops *ops = dev_iommu_ops(dev);
+ struct iommu_domain *blocked_domain = ops->blocked_domain;
+ int ret = 1;
- ops->remove_dev_pasid(dev, pasid, domain);
+ if (blocked_domain && blocked_domain->ops->set_dev_pasid) {
+ ret = blocked_domain->ops->set_dev_pasid(blocked_domain,
+ dev, pasid, domain);
+ } else {
+ ops->remove_dev_pasid(dev, pasid, domain);
+ ret = 0;
+ }
+
+ WARN_ON(ret);
}
static int __iommu_set_group_pasid(struct iommu_domain *domain,
@@ -3380,7 +3390,9 @@ int iommu_attach_device_pasid(struct iommu_domain *domain,
ops = dev_iommu_ops(dev);
if (!domain->ops->set_dev_pasid ||
- !ops->remove_dev_pasid)
+ (!ops->remove_dev_pasid &&
+ (!ops->blocked_domain ||
+ !ops->blocked_domain->ops->set_dev_pasid)))
return -EOPNOTSUPP;
if (ops != domain->owner || pasid == IOMMU_NO_PASID)