@@ -1752,10 +1752,36 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8
17521752 intel_context_flush_present (info , context , did , true);
17531753}
17541754
1755+ static int __domain_setup_first_level (struct intel_iommu * iommu ,
1756+ struct device * dev , ioasid_t pasid ,
1757+ u16 did , pgd_t * pgd , int flags ,
1758+ struct iommu_domain * old )
1759+ {
1760+ if (!old )
1761+ return intel_pasid_setup_first_level (iommu , dev , pgd ,
1762+ pasid , did , flags );
1763+ return intel_pasid_replace_first_level (iommu , dev , pgd , pasid , did ,
1764+ iommu_domain_did (old , iommu ),
1765+ flags );
1766+ }
1767+
1768+ static int domain_setup_second_level (struct intel_iommu * iommu ,
1769+ struct dmar_domain * domain ,
1770+ struct device * dev , ioasid_t pasid ,
1771+ struct iommu_domain * old )
1772+ {
1773+ if (!old )
1774+ return intel_pasid_setup_second_level (iommu , domain ,
1775+ dev , pasid );
1776+ return intel_pasid_replace_second_level (iommu , domain , dev ,
1777+ iommu_domain_did (old , iommu ),
1778+ pasid );
1779+ }
1780+
17551781static int domain_setup_first_level (struct intel_iommu * iommu ,
17561782 struct dmar_domain * domain ,
17571783 struct device * dev ,
1758- u32 pasid )
1784+ u32 pasid , struct iommu_domain * old )
17591785{
17601786 struct dma_pte * pgd = domain -> pgd ;
17611787 int level , flags = 0 ;
@@ -1770,9 +1796,9 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
17701796 if (domain -> force_snooping )
17711797 flags |= PASID_FLAG_PAGE_SNOOP ;
17721798
1773- return intel_pasid_setup_first_level (iommu , dev , ( pgd_t * ) pgd , pasid ,
1774- domain_id_iommu (domain , iommu ),
1775- flags );
1799+ return __domain_setup_first_level (iommu , dev , pasid ,
1800+ domain_id_iommu (domain , iommu ),
1801+ ( pgd_t * ) pgd , flags , old );
17761802}
17771803
17781804static bool dev_is_real_dma_subdevice (struct device * dev )
@@ -1804,9 +1830,11 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
18041830 if (!sm_supported (iommu ))
18051831 ret = domain_context_mapping (domain , dev );
18061832 else if (domain -> use_first_level )
1807- ret = domain_setup_first_level (iommu , domain , dev , IOMMU_NO_PASID );
1833+ ret = domain_setup_first_level (iommu , domain , dev ,
1834+ IOMMU_NO_PASID , NULL );
18081835 else
1809- ret = intel_pasid_setup_second_level (iommu , domain , dev , IOMMU_NO_PASID );
1836+ ret = domain_setup_second_level (iommu , domain , dev ,
1837+ IOMMU_NO_PASID , NULL );
18101838
18111839 if (ret )
18121840 goto out_block_translation ;
@@ -4145,10 +4173,10 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
41454173
41464174 if (dmar_domain -> use_first_level )
41474175 ret = domain_setup_first_level (iommu , dmar_domain ,
4148- dev , pasid );
4176+ dev , pasid , old );
41494177 else
4150- ret = intel_pasid_setup_second_level (iommu , dmar_domain ,
4151- dev , pasid );
4178+ ret = domain_setup_second_level (iommu , dmar_domain ,
4179+ dev , pasid , old );
41524180 if (ret )
41534181 goto out_remove_dev_pasid ;
41544182
0 commit comments