diff options
author | Yi Liu <yi.l.liu@intel.com> | 2024-11-08 10:14:01 +0800 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2024-11-08 14:04:56 +0100 |
commit | 9bc18d283d9a88ab0edc7cc537d24bf534b36110 (patch) | |
tree | 47a63c8662b0357e7ec3fc941d8df0503dd99c9b | |
parent | cfb31f194a1c4b54ea2109bc0fa03e4ee8d4209b (diff) |
iommu/vt-d: Make identity_domain_set_dev_pasid() to handle domain replacement
Let identity_domain_set_dev_pasid() call the pasid replace helpers hence
be able to do domain replacement.
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Link: https://lore.kernel.org/r/20241107122234.7424-11-yi.l.liu@intel.com
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
-rw-r--r-- | drivers/iommu/intel/iommu.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 251cfebe6226..ba984cb4aa44 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1778,6 +1778,17 @@ static int domain_setup_second_level(struct intel_iommu *iommu, pasid); } +static int domain_setup_passthrough(struct intel_iommu *iommu, + struct device *dev, ioasid_t pasid, + struct iommu_domain *old) +{ + if (!old) + return intel_pasid_setup_pass_through(iommu, dev, pasid); + return intel_pasid_replace_pass_through(iommu, dev, + iommu_domain_did(old, iommu), + pasid); +} + static int domain_setup_first_level(struct intel_iommu *iommu, struct dmar_domain *domain, struct device *dev, @@ -4423,11 +4434,17 @@ static int identity_domain_set_dev_pasid(struct iommu_domain *domain, { struct device_domain_info *info = dev_iommu_priv_get(dev); struct intel_iommu *iommu = info->iommu; + int ret; if (!pasid_supported(iommu) || dev_is_real_dma_subdevice(dev)) return -EOPNOTSUPP; - return intel_pasid_setup_pass_through(iommu, dev, pasid); + ret = domain_setup_passthrough(iommu, dev, pasid, old); + if (ret) + return ret; + + domain_remove_dev_pasid(old, dev, pasid); + return 0; } static struct iommu_domain identity_domain = { |