Let intel_iommu_set_dev_pasid() call the pasid replace helpers hence be able to do domain replacement. Signed-off-by: Yi Liu <yi.l.liu@xxxxxxxxx> --- drivers/iommu/intel/iommu.c | 17 +++++++++++------ drivers/iommu/intel/pasid.h | 11 +++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 6bc5ce03c6f5..29a3d9de109c 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1908,7 +1908,7 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8 static int domain_setup_first_level(struct intel_iommu *iommu, struct dmar_domain *domain, struct device *dev, - u32 pasid) + u32 pasid, struct iommu_domain *old) { struct dma_pte *pgd = domain->pgd; int agaw, level; @@ -1934,6 +1934,11 @@ static int domain_setup_first_level(struct intel_iommu *iommu, if (domain->force_snooping) flags |= PASID_FLAG_PAGE_SNOOP; + if (old) + return intel_pasid_replace_first_level(iommu, dev, + (pgd_t *)pgd, pasid, + domain_id_iommu(domain, iommu), + flags); return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid, domain_id_iommu(domain, iommu), flags); @@ -1968,9 +1973,9 @@ static int dmar_domain_attach_device(struct dmar_domain *domain, if (!sm_supported(iommu)) ret = domain_context_mapping(domain, dev); else if (domain->use_first_level) - ret = domain_setup_first_level(iommu, domain, dev, IOMMU_NO_PASID); + ret = domain_setup_first_level(iommu, domain, dev, IOMMU_NO_PASID, NULL); else - ret = intel_pasid_setup_second_level(iommu, domain, dev, IOMMU_NO_PASID); + ret = domain_setup_second_level(iommu, domain, dev, IOMMU_NO_PASID, NULL); if (ret) goto out_block_translation; @@ -4363,10 +4368,10 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain, if (dmar_domain->use_first_level) ret = domain_setup_first_level(iommu, dmar_domain, - dev, pasid); + dev, pasid, old); else - ret = intel_pasid_setup_second_level(iommu, dmar_domain, - dev, pasid); + ret = domain_setup_second_level(iommu, dmar_domain, + dev, pasid, old); if (ret) goto out_remove_dev_pasid; diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h index 228938f3be51..3f82f69a7bce 100644 --- a/drivers/iommu/intel/pasid.h +++ b/drivers/iommu/intel/pasid.h @@ -315,6 +315,17 @@ int intel_pasid_replace_nested(struct intel_iommu *iommu, struct device *dev, u32 pasid, struct dmar_domain *domain); +static inline int domain_setup_second_level(struct intel_iommu *iommu, + struct dmar_domain *domain, + struct device *dev, ioasid_t pasid, + struct iommu_domain *old) +{ + if (old) + return intel_pasid_replace_second_level(iommu, domain, + dev, pasid); + return intel_pasid_setup_second_level(iommu, domain, dev, pasid); +} + void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev, u32 pasid, bool fault_ignore); -- 2.34.1