@@ -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;
@@ -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);
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@intel.com> --- drivers/iommu/intel/iommu.c | 17 +++++++++++------ drivers/iommu/intel/pasid.h | 11 +++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-)