@@ -571,13 +571,32 @@ static struct kmem_cache *iommu_devinfo_cache;
571
571
572
572
static struct dmar_domain * get_iommu_domain (struct intel_iommu * iommu , u16 did )
573
573
{
574
- return iommu -> domains [did ];
574
+ struct dmar_domain * * domains ;
575
+ int idx = did >> 8 ;
576
+
577
+ domains = iommu -> domains [idx ];
578
+ if (!domains )
579
+ return NULL ;
580
+
581
+ return domains [did & 0xff ];
575
582
}
576
583
577
584
static void set_iommu_domain (struct intel_iommu * iommu , u16 did ,
578
585
struct dmar_domain * domain )
579
586
{
580
- iommu -> domains [did ] = domain ;
587
+ struct dmar_domain * * domains ;
588
+ int idx = did >> 8 ;
589
+
590
+ if (!iommu -> domains [idx ]) {
591
+ size_t size = 256 * sizeof (struct dmar_domain * );
592
+ iommu -> domains [idx ] = kzalloc (size , GFP_ATOMIC );
593
+ }
594
+
595
+ domains = iommu -> domains [idx ];
596
+ if (WARN_ON (!domains ))
597
+ return ;
598
+ else
599
+ domains [did & 0xff ] = domain ;
581
600
}
582
601
583
602
static inline void * alloc_pgtable_page (int node )
@@ -1530,35 +1549,43 @@ static void iommu_disable_translation(struct intel_iommu *iommu)
1530
1549
1531
1550
static int iommu_init_domains (struct intel_iommu * iommu )
1532
1551
{
1533
- unsigned long ndomains ;
1534
- unsigned long nlongs ;
1552
+ u32 ndomains , nlongs ;
1553
+ size_t size ;
1535
1554
1536
1555
ndomains = cap_ndoms (iommu -> cap );
1537
- pr_debug ("%s: Number of Domains supported <%ld >\n" ,
1556
+ pr_debug ("%s: Number of Domains supported <%d >\n" ,
1538
1557
iommu -> name , ndomains );
1539
1558
nlongs = BITS_TO_LONGS (ndomains );
1540
1559
1541
1560
spin_lock_init (& iommu -> lock );
1542
1561
1543
- /* TBD: there might be 64K domains,
1544
- * consider other allocation for future chip
1545
- */
1546
1562
iommu -> domain_ids = kcalloc (nlongs , sizeof (unsigned long ), GFP_KERNEL );
1547
1563
if (!iommu -> domain_ids ) {
1548
1564
pr_err ("%s: Allocating domain id array failed\n" ,
1549
1565
iommu -> name );
1550
1566
return - ENOMEM ;
1551
1567
}
1552
- iommu -> domains = kcalloc (ndomains , sizeof (struct dmar_domain * ),
1553
- GFP_KERNEL );
1554
- if (!iommu -> domains ) {
1568
+
1569
+ size = ((ndomains >> 8 ) + 1 ) * sizeof (struct dmar_domain * * );
1570
+ iommu -> domains = kzalloc (size , GFP_KERNEL );
1571
+
1572
+ if (iommu -> domains ) {
1573
+ size = 256 * sizeof (struct dmar_domain * );
1574
+ iommu -> domains [0 ] = kzalloc (size , GFP_KERNEL );
1575
+ }
1576
+
1577
+ if (!iommu -> domains || !iommu -> domains [0 ]) {
1555
1578
pr_err ("%s: Allocating domain array failed\n" ,
1556
1579
iommu -> name );
1557
1580
kfree (iommu -> domain_ids );
1581
+ kfree (iommu -> domains );
1558
1582
iommu -> domain_ids = NULL ;
1583
+ iommu -> domains = NULL ;
1559
1584
return - ENOMEM ;
1560
1585
}
1561
1586
1587
+
1588
+
1562
1589
/*
1563
1590
* If Caching mode is set, then invalid translations are tagged
1564
1591
* with domain-id 0, hence we need to pre-allocate it. We also
@@ -1600,6 +1627,11 @@ static void disable_dmar_iommu(struct intel_iommu *iommu)
1600
1627
static void free_dmar_iommu (struct intel_iommu * iommu )
1601
1628
{
1602
1629
if ((iommu -> domains ) && (iommu -> domain_ids )) {
1630
+ int elems = (cap_ndoms (iommu -> cap ) >> 8 ) + 1 ;
1631
+ int i ;
1632
+
1633
+ for (i = 0 ; i < elems ; i ++ )
1634
+ kfree (iommu -> domains [i ]);
1603
1635
kfree (iommu -> domains );
1604
1636
kfree (iommu -> domain_ids );
1605
1637
iommu -> domains = NULL ;
0 commit comments