aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/iommu/intel-iommu.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 8aa580dc3033..a08a53448b72 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -354,10 +354,18 @@ static int hw_pass_through = 1;
354/* si_domain contains mulitple devices */ 354/* si_domain contains mulitple devices */
355#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2) 355#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2)
356 356
357/* define the limit of IOMMUs supported in each domain */
358#ifdef CONFIG_X86
359# define IOMMU_UNITS_SUPPORTED MAX_IO_APICS
360#else
361# define IOMMU_UNITS_SUPPORTED 64
362#endif
363
357struct dmar_domain { 364struct dmar_domain {
358 int id; /* domain id */ 365 int id; /* domain id */
359 int nid; /* node id */ 366 int nid; /* node id */
360 unsigned long iommu_bmp; /* bitmap of iommus this domain uses*/ 367 DECLARE_BITMAP(iommu_bmp, IOMMU_UNITS_SUPPORTED);
368 /* bitmap of iommus this domain uses*/
361 369
362 struct list_head devices; /* all devices' list */ 370 struct list_head devices; /* all devices' list */
363 struct iova_domain iovad; /* iova's that belong to this domain */ 371 struct iova_domain iovad; /* iova's that belong to this domain */
@@ -569,7 +577,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
569 BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); 577 BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE);
570 BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY); 578 BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
571 579
572 iommu_id = find_first_bit(&domain->iommu_bmp, g_num_of_iommus); 580 iommu_id = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
573 if (iommu_id < 0 || iommu_id >= g_num_of_iommus) 581 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
574 return NULL; 582 return NULL;
575 583
@@ -582,7 +590,7 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
582 590
583 domain->iommu_coherency = 1; 591 domain->iommu_coherency = 1;
584 592
585 for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { 593 for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
586 if (!ecap_coherent(g_iommus[i]->ecap)) { 594 if (!ecap_coherent(g_iommus[i]->ecap)) {
587 domain->iommu_coherency = 0; 595 domain->iommu_coherency = 0;
588 break; 596 break;
@@ -596,7 +604,7 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain)
596 604
597 domain->iommu_snooping = 1; 605 domain->iommu_snooping = 1;
598 606
599 for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) { 607 for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
600 if (!ecap_sc_support(g_iommus[i]->ecap)) { 608 if (!ecap_sc_support(g_iommus[i]->ecap)) {
601 domain->iommu_snooping = 0; 609 domain->iommu_snooping = 0;
602 break; 610 break;
@@ -1332,7 +1340,7 @@ static struct dmar_domain *alloc_domain(void)
1332 return NULL; 1340 return NULL;
1333 1341
1334 domain->nid = -1; 1342 domain->nid = -1;
1335 memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); 1343 memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
1336 domain->flags = 0; 1344 domain->flags = 0;
1337 1345
1338 return domain; 1346 return domain;
@@ -1358,7 +1366,7 @@ static int iommu_attach_domain(struct dmar_domain *domain,
1358 1366
1359 domain->id = num; 1367 domain->id = num;
1360 set_bit(num, iommu->domain_ids); 1368 set_bit(num, iommu->domain_ids);
1361 set_bit(iommu->seq_id, &domain->iommu_bmp); 1369 set_bit(iommu->seq_id, domain->iommu_bmp);
1362 iommu->domains[num] = domain; 1370 iommu->domains[num] = domain;
1363 spin_unlock_irqrestore(&iommu->lock, flags); 1371 spin_unlock_irqrestore(&iommu->lock, flags);
1364 1372
@@ -1383,7 +1391,7 @@ static void iommu_detach_domain(struct dmar_domain *domain,
1383 1391
1384 if (found) { 1392 if (found) {
1385 clear_bit(num, iommu->domain_ids); 1393 clear_bit(num, iommu->domain_ids);
1386 clear_bit(iommu->seq_id, &domain->iommu_bmp); 1394 clear_bit(iommu->seq_id, domain->iommu_bmp);
1387 iommu->domains[num] = NULL; 1395 iommu->domains[num] = NULL;
1388 } 1396 }
1389 spin_unlock_irqrestore(&iommu->lock, flags); 1397 spin_unlock_irqrestore(&iommu->lock, flags);
@@ -1525,7 +1533,7 @@ static void domain_exit(struct dmar_domain *domain)
1525 dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); 1533 dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
1526 1534
1527 for_each_active_iommu(iommu, drhd) 1535 for_each_active_iommu(iommu, drhd)
1528 if (test_bit(iommu->seq_id, &domain->iommu_bmp)) 1536 if (test_bit(iommu->seq_id, domain->iommu_bmp))
1529 iommu_detach_domain(domain, iommu); 1537 iommu_detach_domain(domain, iommu);
1530 1538
1531 free_domain_mem(domain); 1539 free_domain_mem(domain);
@@ -1651,7 +1659,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
1651 spin_unlock_irqrestore(&iommu->lock, flags); 1659 spin_unlock_irqrestore(&iommu->lock, flags);
1652 1660
1653 spin_lock_irqsave(&domain->iommu_lock, flags); 1661 spin_lock_irqsave(&domain->iommu_lock, flags);
1654 if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { 1662 if (!test_and_set_bit(iommu->seq_id, domain->iommu_bmp)) {
1655 domain->iommu_count++; 1663 domain->iommu_count++;
1656 if (domain->iommu_count == 1) 1664 if (domain->iommu_count == 1)
1657 domain->nid = iommu->node; 1665 domain->nid = iommu->node;
@@ -2400,12 +2408,17 @@ static int __init init_dmars(void)
2400 * endfor 2408 * endfor
2401 */ 2409 */
2402 for_each_drhd_unit(drhd) { 2410 for_each_drhd_unit(drhd) {
2403 g_num_of_iommus++;
2404 /* 2411 /*
2405 * lock not needed as this is only incremented in the single 2412 * lock not needed as this is only incremented in the single
2406 * threaded kernel __init code path all other access are read 2413 * threaded kernel __init code path all other access are read
2407 * only 2414 * only
2408 */ 2415 */
2416 if (g_num_of_iommus < IOMMU_UNITS_SUPPORTED) {
2417 g_num_of_iommus++;
2418 continue;
2419 }
2420 printk_once(KERN_ERR "intel-iommu: exceeded %d IOMMUs\n",
2421 IOMMU_UNITS_SUPPORTED);
2409 } 2422 }
2410 2423
2411 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), 2424 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
@@ -3746,7 +3759,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
3746 if (found == 0) { 3759 if (found == 0) {
3747 unsigned long tmp_flags; 3760 unsigned long tmp_flags;
3748 spin_lock_irqsave(&domain->iommu_lock, tmp_flags); 3761 spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
3749 clear_bit(iommu->seq_id, &domain->iommu_bmp); 3762 clear_bit(iommu->seq_id, domain->iommu_bmp);
3750 domain->iommu_count--; 3763 domain->iommu_count--;
3751 domain_update_iommu_cap(domain); 3764 domain_update_iommu_cap(domain);
3752 spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); 3765 spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
@@ -3788,7 +3801,7 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
3788 */ 3801 */
3789 spin_lock_irqsave(&domain->iommu_lock, flags2); 3802 spin_lock_irqsave(&domain->iommu_lock, flags2);
3790 if (test_and_clear_bit(iommu->seq_id, 3803 if (test_and_clear_bit(iommu->seq_id,
3791 &domain->iommu_bmp)) { 3804 domain->iommu_bmp)) {
3792 domain->iommu_count--; 3805 domain->iommu_count--;
3793 domain_update_iommu_cap(domain); 3806 domain_update_iommu_cap(domain);
3794 } 3807 }
@@ -3813,7 +3826,7 @@ static struct dmar_domain *iommu_alloc_vm_domain(void)
3813 3826
3814 domain->id = vm_domid++; 3827 domain->id = vm_domid++;
3815 domain->nid = -1; 3828 domain->nid = -1;
3816 memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); 3829 memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
3817 domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; 3830 domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
3818 3831
3819 return domain; 3832 return domain;