[PATCH v4 06/13] iommu/vt-d: Make intel_iommu_set_dev_pasid() to handle domain replacement

Yi Liu
2024-11-04T13:18:53Z

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(-)

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