@@ -254,10 +254,6 @@ static inline void context_clear_entry(struct context_entry *context)
254254static struct dmar_domain * si_domain ;
255255static int hw_pass_through = 1 ;
256256
257- #define for_each_domain_iommu (idx , domain ) \
258- for (idx = 0; idx < g_num_of_iommus; idx++) \
259- if (domain->iommu_refcnt[idx])
260-
261257struct dmar_rmrr_unit {
262258 struct list_head list ; /* list of rmrr units */
263259 struct acpi_dmar_header * hdr ; /* ACPI header */
@@ -453,16 +449,16 @@ static inline bool iommu_paging_structure_coherency(struct intel_iommu *iommu)
453449
454450static void domain_update_iommu_coherency (struct dmar_domain * domain )
455451{
452+ struct iommu_domain_info * info ;
456453 struct dmar_drhd_unit * drhd ;
457454 struct intel_iommu * iommu ;
458455 bool found = false;
459- int i ;
456+ unsigned long i ;
460457
461458 domain -> iommu_coherency = true;
462-
463- for_each_domain_iommu (i , domain ) {
459+ xa_for_each (& domain -> iommu_array , i , info ) {
464460 found = true;
465- if (!iommu_paging_structure_coherency (g_iommus [ i ] )) {
461+ if (!iommu_paging_structure_coherency (info -> iommu )) {
466462 domain -> iommu_coherency = false;
467463 break ;
468464 }
@@ -1495,7 +1491,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
14951491 unsigned int aligned_pages = __roundup_pow_of_two (pages );
14961492 unsigned int mask = ilog2 (aligned_pages );
14971493 uint64_t addr = (uint64_t )pfn << VTD_PAGE_SHIFT ;
1498- u16 did = domain -> iommu_did [ iommu -> seq_id ] ;
1494+ u16 did = domain_id_iommu ( domain , iommu ) ;
14991495
15001496 BUG_ON (pages == 0 );
15011497
@@ -1565,11 +1561,12 @@ static inline void __mapping_notify_one(struct intel_iommu *iommu,
15651561static void intel_flush_iotlb_all (struct iommu_domain * domain )
15661562{
15671563 struct dmar_domain * dmar_domain = to_dmar_domain (domain );
1568- int idx ;
1564+ struct iommu_domain_info * info ;
1565+ unsigned long idx ;
15691566
1570- for_each_domain_iommu ( idx , dmar_domain ) {
1571- struct intel_iommu * iommu = g_iommus [ idx ] ;
1572- u16 did = dmar_domain -> iommu_did [ iommu -> seq_id ] ;
1567+ xa_for_each ( & dmar_domain -> iommu_array , idx , info ) {
1568+ struct intel_iommu * iommu = info -> iommu ;
1569+ u16 did = domain_id_iommu ( dmar_domain , iommu ) ;
15731570
15741571 if (domain_use_first_level (dmar_domain ))
15751572 qi_flush_piotlb (iommu , did , PASID_RID2PASID , 0 , -1 , 0 );
@@ -1745,52 +1742,74 @@ static struct dmar_domain *alloc_domain(unsigned int type)
17451742 domain -> has_iotlb_device = false;
17461743 INIT_LIST_HEAD (& domain -> devices );
17471744 spin_lock_init (& domain -> lock );
1745+ xa_init (& domain -> iommu_array );
17481746
17491747 return domain ;
17501748}
17511749
17521750static int domain_attach_iommu (struct dmar_domain * domain ,
17531751 struct intel_iommu * iommu )
17541752{
1753+ struct iommu_domain_info * info , * curr ;
17551754 unsigned long ndomains ;
1756- int num , ret = 0 ;
1755+ int num , ret = - ENOSPC ;
1756+
1757+ info = kzalloc (sizeof (* info ), GFP_KERNEL );
1758+ if (!info )
1759+ return - ENOMEM ;
17571760
17581761 spin_lock (& iommu -> lock );
1759- domain -> iommu_refcnt [iommu -> seq_id ] += 1 ;
1760- if (domain -> iommu_refcnt [iommu -> seq_id ] == 1 ) {
1761- ndomains = cap_ndoms (iommu -> cap );
1762- num = find_first_zero_bit (iommu -> domain_ids , ndomains );
1763-
1764- if (num >= ndomains ) {
1765- pr_err ("%s: No free domain ids\n" , iommu -> name );
1766- domain -> iommu_refcnt [iommu -> seq_id ] -= 1 ;
1767- ret = - ENOSPC ;
1768- goto out_unlock ;
1769- }
1762+ curr = xa_load (& domain -> iommu_array , iommu -> seq_id );
1763+ if (curr ) {
1764+ curr -> refcnt ++ ;
1765+ spin_unlock (& iommu -> lock );
1766+ kfree (info );
1767+ return 0 ;
1768+ }
17701769
1771- set_bit (num , iommu -> domain_ids );
1772- domain -> iommu_did [iommu -> seq_id ] = num ;
1773- domain -> nid = iommu -> node ;
1774- domain_update_iommu_cap (domain );
1770+ ndomains = cap_ndoms (iommu -> cap );
1771+ num = find_first_zero_bit (iommu -> domain_ids , ndomains );
1772+ if (num >= ndomains ) {
1773+ pr_err ("%s: No free domain ids\n" , iommu -> name );
1774+ goto err_unlock ;
17751775 }
17761776
1777- out_unlock :
1777+ set_bit (num , iommu -> domain_ids );
1778+ info -> refcnt = 1 ;
1779+ info -> did = num ;
1780+ info -> iommu = iommu ;
1781+ curr = xa_cmpxchg (& domain -> iommu_array , iommu -> seq_id ,
1782+ NULL , info , GFP_ATOMIC );
1783+ if (curr ) {
1784+ ret = xa_err (curr ) ? : - EBUSY ;
1785+ goto err_clear ;
1786+ }
1787+ domain_update_iommu_cap (domain );
1788+
17781789 spin_unlock (& iommu -> lock );
1790+ return 0 ;
1791+
1792+ err_clear :
1793+ clear_bit (info -> did , iommu -> domain_ids );
1794+ err_unlock :
1795+ spin_unlock (& iommu -> lock );
1796+ kfree (info );
17791797 return ret ;
17801798}
17811799
17821800static void domain_detach_iommu (struct dmar_domain * domain ,
17831801 struct intel_iommu * iommu )
17841802{
1785- int num ;
1803+ struct iommu_domain_info * info ;
17861804
17871805 spin_lock (& iommu -> lock );
1788- domain -> iommu_refcnt [iommu -> seq_id ] -= 1 ;
1789- if (domain -> iommu_refcnt [iommu -> seq_id ] == 0 ) {
1790- num = domain -> iommu_did [iommu -> seq_id ];
1791- clear_bit (num , iommu -> domain_ids );
1806+ info = xa_load (& domain -> iommu_array , iommu -> seq_id );
1807+ if (-- info -> refcnt == 0 ) {
1808+ clear_bit (info -> did , iommu -> domain_ids );
1809+ xa_erase (& domain -> iommu_array , iommu -> seq_id );
1810+ domain -> nid = NUMA_NO_NODE ;
17921811 domain_update_iommu_cap (domain );
1793- domain -> iommu_did [ iommu -> seq_id ] = 0 ;
1812+ kfree ( info ) ;
17941813 }
17951814 spin_unlock (& iommu -> lock );
17961815}
@@ -1880,7 +1899,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
18801899{
18811900 struct device_domain_info * info =
18821901 iommu_support_dev_iotlb (domain , iommu , bus , devfn );
1883- u16 did = domain -> iommu_did [ iommu -> seq_id ] ;
1902+ u16 did = domain_id_iommu ( domain , iommu ) ;
18841903 int translation = CONTEXT_TT_MULTI_LEVEL ;
18851904 struct context_entry * context ;
18861905 int ret ;
@@ -2129,8 +2148,9 @@ static void switch_to_super_page(struct dmar_domain *domain,
21292148 unsigned long end_pfn , int level )
21302149{
21312150 unsigned long lvl_pages = lvl_to_nr_pages (level );
2151+ struct iommu_domain_info * info ;
21322152 struct dma_pte * pte = NULL ;
2133- int i ;
2153+ unsigned long i ;
21342154
21352155 while (start_pfn <= end_pfn ) {
21362156 if (!pte )
@@ -2141,8 +2161,8 @@ static void switch_to_super_page(struct dmar_domain *domain,
21412161 start_pfn + lvl_pages - 1 ,
21422162 level + 1 );
21432163
2144- for_each_domain_iommu ( i , domain )
2145- iommu_flush_iotlb_psi (g_iommus [ i ] , domain ,
2164+ xa_for_each ( & domain -> iommu_array , i , info )
2165+ iommu_flush_iotlb_psi (info -> iommu , domain ,
21462166 start_pfn , lvl_pages ,
21472167 0 , 0 );
21482168 }
@@ -2272,7 +2292,7 @@ static void domain_context_clear_one(struct device_domain_info *info, u8 bus, u8
22722292 if (hw_pass_through && domain_type_is_si (info -> domain ))
22732293 did_old = FLPT_DEFAULT_DID ;
22742294 else
2275- did_old = info -> domain -> iommu_did [ iommu -> seq_id ] ;
2295+ did_old = domain_id_iommu ( info -> domain , iommu ) ;
22762296 } else {
22772297 did_old = context_domain_id (context );
22782298 }
@@ -2330,7 +2350,7 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
23302350 flags |= PASID_FLAG_PAGE_SNOOP ;
23312351
23322352 return intel_pasid_setup_first_level (iommu , dev , (pgd_t * )pgd , pasid ,
2333- domain -> iommu_did [ iommu -> seq_id ] ,
2353+ domain_id_iommu ( domain , iommu ) ,
23342354 flags );
23352355}
23362356
@@ -4368,15 +4388,16 @@ static void intel_iommu_tlb_sync(struct iommu_domain *domain,
43684388 struct dmar_domain * dmar_domain = to_dmar_domain (domain );
43694389 unsigned long iova_pfn = IOVA_PFN (gather -> start );
43704390 size_t size = gather -> end - gather -> start ;
4391+ struct iommu_domain_info * info ;
43714392 unsigned long start_pfn ;
43724393 unsigned long nrpages ;
4373- int iommu_id ;
4394+ unsigned long i ;
43744395
43754396 nrpages = aligned_nrpages (gather -> start , size );
43764397 start_pfn = mm_to_dma_pfn (iova_pfn );
43774398
4378- for_each_domain_iommu ( iommu_id , dmar_domain )
4379- iommu_flush_iotlb_psi (g_iommus [ iommu_id ] , dmar_domain ,
4399+ xa_for_each ( & dmar_domain -> iommu_array , i , info )
4400+ iommu_flush_iotlb_psi (info -> iommu , dmar_domain ,
43804401 start_pfn , nrpages ,
43814402 list_empty (& gather -> freelist ), 0 );
43824403
@@ -4620,7 +4641,7 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
46204641 context [0 ].lo = ctx_lo ;
46214642 wmb ();
46224643 iommu -> flush .flush_context (iommu ,
4623- domain -> iommu_did [ iommu -> seq_id ] ,
4644+ domain_id_iommu ( domain , iommu ) ,
46244645 PCI_DEVID (info -> bus , info -> devfn ),
46254646 DMA_CCMD_MASK_NOBIT ,
46264647 DMA_CCMD_DEVICE_INVL );
@@ -4757,13 +4778,11 @@ static void intel_iommu_iotlb_sync_map(struct iommu_domain *domain,
47574778 struct dmar_domain * dmar_domain = to_dmar_domain (domain );
47584779 unsigned long pages = aligned_nrpages (iova , size );
47594780 unsigned long pfn = iova >> VTD_PAGE_SHIFT ;
4760- struct intel_iommu * iommu ;
4761- int iommu_id ;
4781+ struct iommu_domain_info * info ;
4782+ unsigned long i ;
47624783
4763- for_each_domain_iommu (iommu_id , dmar_domain ) {
4764- iommu = g_iommus [iommu_id ];
4765- __mapping_notify_one (iommu , dmar_domain , pfn , pages );
4766- }
4784+ xa_for_each (& dmar_domain -> iommu_array , i , info )
4785+ __mapping_notify_one (info -> iommu , dmar_domain , pfn , pages );
47674786}
47684787
47694788const struct iommu_ops intel_iommu_ops = {
0 commit comments