@@ -1752,10 +1752,36 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8
1752
1752
intel_context_flush_present (info , context , did , true);
1753
1753
}
1754
1754
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
+
1755
1781
static int domain_setup_first_level (struct intel_iommu * iommu ,
1756
1782
struct dmar_domain * domain ,
1757
1783
struct device * dev ,
1758
- u32 pasid )
1784
+ u32 pasid , struct iommu_domain * old )
1759
1785
{
1760
1786
struct dma_pte * pgd = domain -> pgd ;
1761
1787
int level , flags = 0 ;
@@ -1770,9 +1796,9 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
1770
1796
if (domain -> force_snooping )
1771
1797
flags |= PASID_FLAG_PAGE_SNOOP ;
1772
1798
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 );
1776
1802
}
1777
1803
1778
1804
static bool dev_is_real_dma_subdevice (struct device * dev )
@@ -1804,9 +1830,11 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
1804
1830
if (!sm_supported (iommu ))
1805
1831
ret = domain_context_mapping (domain , dev );
1806
1832
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 );
1808
1835
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 );
1810
1838
1811
1839
if (ret )
1812
1840
goto out_block_translation ;
@@ -4145,10 +4173,10 @@ static int intel_iommu_set_dev_pasid(struct iommu_domain *domain,
4145
4173
4146
4174
if (dmar_domain -> use_first_level )
4147
4175
ret = domain_setup_first_level (iommu , dmar_domain ,
4148
- dev , pasid );
4176
+ dev , pasid , old );
4149
4177
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 );
4152
4180
if (ret )
4153
4181
goto out_remove_dev_pasid ;
4154
4182
0 commit comments