aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2012-03-05 18:05:16 -0500
committerIngo Molnar <mingo@elte.hu>2012-03-06 03:00:02 -0500
commit1b198bb04ad72669d4bd6575fc9945ed595bfee0 (patch)
tree648ccc3d5520b23f1ef919251e824828e15a3090 /drivers/iommu
parenteae460b6590bb924d4e528d6cc7ccd4d993ff8dd (diff)
x86/iommu/intel: Increase the number of iommus supported to MAX_IO_APICS
The number of IOMMUs supported should be the same as the number of IO APICS. This limit comes into play when the IOMMUs are identity mapped, thus the number of possible IOMMUs in the "static identity" (si) domain should be this same number. Signed-off-by: Mike Travis <travis@sgi.com> Signed-off-by: Jack Steiner <steiner@sgi.com> Cc: Jack Steiner <steiner@sgi.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Chris Wright <chrisw@sous-sol.org> Cc: Daniel Rahn <drahn@suse.com> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Cc: Joerg Roedel <joerg.roedel@amd.com> [ Fixed printk format string, cleaned up the code ] Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/n/tip-ixcmp0hfp0a3b2lfv3uo0p0x@git.kernel.org Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/iommu')
-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;