aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/intel-iommu.c61
1 files changed, 36 insertions, 25 deletions
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index c9c6053198d4..132f93b05154 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -48,8 +48,6 @@
48#define ROOT_SIZE VTD_PAGE_SIZE 48#define ROOT_SIZE VTD_PAGE_SIZE
49#define CONTEXT_SIZE VTD_PAGE_SIZE 49#define CONTEXT_SIZE VTD_PAGE_SIZE
50 50
51#define IS_BRIDGE_HOST_DEVICE(pdev) \
52 ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
53#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) 51#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
54#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) 52#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
55#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e) 53#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
@@ -356,10 +354,18 @@ static int hw_pass_through = 1;
356/* si_domain contains mulitple devices */ 354/* si_domain contains mulitple devices */
357#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2) 355#define DOMAIN_FLAG_STATIC_IDENTITY (1 << 2)
358 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
359struct dmar_domain { 364struct dmar_domain {
360 int id; /* domain id */ 365 int id; /* domain id */
361 int nid; /* node id */ 366 int nid; /* node id */
362 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*/
363 369
364 struct list_head devices; /* all devices' list */ 370 struct list_head devices; /* all devices' list */
365 struct iova_domain iovad; /* iova's that belong to this domain */ 371 struct iova_domain iovad; /* iova's that belong to this domain */
@@ -571,7 +577,7 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
571 BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE); 577 BUG_ON(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE);
572 BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY); 578 BUG_ON(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY);
573 579
574 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);
575 if (iommu_id < 0 || iommu_id >= g_num_of_iommus) 581 if (iommu_id < 0 || iommu_id >= g_num_of_iommus)
576 return NULL; 582 return NULL;
577 583
@@ -584,7 +590,7 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
584 590
585 domain->iommu_coherency = 1; 591 domain->iommu_coherency = 1;
586 592
587 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) {
588 if (!ecap_coherent(g_iommus[i]->ecap)) { 594 if (!ecap_coherent(g_iommus[i]->ecap)) {
589 domain->iommu_coherency = 0; 595 domain->iommu_coherency = 0;
590 break; 596 break;
@@ -598,7 +604,7 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain)
598 604
599 domain->iommu_snooping = 1; 605 domain->iommu_snooping = 1;
600 606
601 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) {
602 if (!ecap_sc_support(g_iommus[i]->ecap)) { 608 if (!ecap_sc_support(g_iommus[i]->ecap)) {
603 domain->iommu_snooping = 0; 609 domain->iommu_snooping = 0;
604 break; 610 break;
@@ -1241,7 +1247,7 @@ static int iommu_init_domains(struct intel_iommu *iommu)
1241 unsigned long nlongs; 1247 unsigned long nlongs;
1242 1248
1243 ndomains = cap_ndoms(iommu->cap); 1249 ndomains = cap_ndoms(iommu->cap);
1244 pr_debug("IOMMU %d: Number of Domains supportd <%ld>\n", iommu->seq_id, 1250 pr_debug("IOMMU %d: Number of Domains supported <%ld>\n", iommu->seq_id,
1245 ndomains); 1251 ndomains);
1246 nlongs = BITS_TO_LONGS(ndomains); 1252 nlongs = BITS_TO_LONGS(ndomains);
1247 1253
@@ -1334,7 +1340,7 @@ static struct dmar_domain *alloc_domain(void)
1334 return NULL; 1340 return NULL;
1335 1341
1336 domain->nid = -1; 1342 domain->nid = -1;
1337 memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); 1343 memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
1338 domain->flags = 0; 1344 domain->flags = 0;
1339 1345
1340 return domain; 1346 return domain;
@@ -1360,7 +1366,7 @@ static int iommu_attach_domain(struct dmar_domain *domain,
1360 1366
1361 domain->id = num; 1367 domain->id = num;
1362 set_bit(num, iommu->domain_ids); 1368 set_bit(num, iommu->domain_ids);
1363 set_bit(iommu->seq_id, &domain->iommu_bmp); 1369 set_bit(iommu->seq_id, domain->iommu_bmp);
1364 iommu->domains[num] = domain; 1370 iommu->domains[num] = domain;
1365 spin_unlock_irqrestore(&iommu->lock, flags); 1371 spin_unlock_irqrestore(&iommu->lock, flags);
1366 1372
@@ -1385,7 +1391,7 @@ static void iommu_detach_domain(struct dmar_domain *domain,
1385 1391
1386 if (found) { 1392 if (found) {
1387 clear_bit(num, iommu->domain_ids); 1393 clear_bit(num, iommu->domain_ids);
1388 clear_bit(iommu->seq_id, &domain->iommu_bmp); 1394 clear_bit(iommu->seq_id, domain->iommu_bmp);
1389 iommu->domains[num] = NULL; 1395 iommu->domains[num] = NULL;
1390 } 1396 }
1391 spin_unlock_irqrestore(&iommu->lock, flags); 1397 spin_unlock_irqrestore(&iommu->lock, flags);
@@ -1527,7 +1533,7 @@ static void domain_exit(struct dmar_domain *domain)
1527 dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw)); 1533 dma_pte_free_pagetable(domain, 0, DOMAIN_MAX_PFN(domain->gaw));
1528 1534
1529 for_each_active_iommu(iommu, drhd) 1535 for_each_active_iommu(iommu, drhd)
1530 if (test_bit(iommu->seq_id, &domain->iommu_bmp)) 1536 if (test_bit(iommu->seq_id, domain->iommu_bmp))
1531 iommu_detach_domain(domain, iommu); 1537 iommu_detach_domain(domain, iommu);
1532 1538
1533 free_domain_mem(domain); 1539 free_domain_mem(domain);
@@ -1653,7 +1659,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain, int segment,
1653 spin_unlock_irqrestore(&iommu->lock, flags); 1659 spin_unlock_irqrestore(&iommu->lock, flags);
1654 1660
1655 spin_lock_irqsave(&domain->iommu_lock, flags); 1661 spin_lock_irqsave(&domain->iommu_lock, flags);
1656 if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) { 1662 if (!test_and_set_bit(iommu->seq_id, domain->iommu_bmp)) {
1657 domain->iommu_count++; 1663 domain->iommu_count++;
1658 if (domain->iommu_count == 1) 1664 if (domain->iommu_count == 1)
1659 domain->nid = iommu->node; 1665 domain->nid = iommu->node;
@@ -2369,18 +2375,18 @@ static int __init iommu_prepare_static_identity_mapping(int hw)
2369 return -EFAULT; 2375 return -EFAULT;
2370 2376
2371 for_each_pci_dev(pdev) { 2377 for_each_pci_dev(pdev) {
2372 /* Skip Host/PCI Bridge devices */
2373 if (IS_BRIDGE_HOST_DEVICE(pdev))
2374 continue;
2375 if (iommu_should_identity_map(pdev, 1)) { 2378 if (iommu_should_identity_map(pdev, 1)) {
2376 printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n",
2377 hw ? "hardware" : "software", pci_name(pdev));
2378
2379 ret = domain_add_dev_info(si_domain, pdev, 2379 ret = domain_add_dev_info(si_domain, pdev,
2380 hw ? CONTEXT_TT_PASS_THROUGH : 2380 hw ? CONTEXT_TT_PASS_THROUGH :
2381 CONTEXT_TT_MULTI_LEVEL); 2381 CONTEXT_TT_MULTI_LEVEL);
2382 if (ret) 2382 if (ret) {
2383 /* device not associated with an iommu */
2384 if (ret == -ENODEV)
2385 continue;
2383 return ret; 2386 return ret;
2387 }
2388 pr_info("IOMMU: %s identity mapping for device %s\n",
2389 hw ? "hardware" : "software", pci_name(pdev));
2384 } 2390 }
2385 } 2391 }
2386 2392
@@ -2402,12 +2408,17 @@ static int __init init_dmars(void)
2402 * endfor 2408 * endfor
2403 */ 2409 */
2404 for_each_drhd_unit(drhd) { 2410 for_each_drhd_unit(drhd) {
2405 g_num_of_iommus++;
2406 /* 2411 /*
2407 * lock not needed as this is only incremented in the single 2412 * lock not needed as this is only incremented in the single
2408 * threaded kernel __init code path all other access are read 2413 * threaded kernel __init code path all other access are read
2409 * only 2414 * only
2410 */ 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);
2411 } 2422 }
2412 2423
2413 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *), 2424 g_iommus = kcalloc(g_num_of_iommus, sizeof(struct intel_iommu *),
@@ -3748,7 +3759,7 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
3748 if (found == 0) { 3759 if (found == 0) {
3749 unsigned long tmp_flags; 3760 unsigned long tmp_flags;
3750 spin_lock_irqsave(&domain->iommu_lock, tmp_flags); 3761 spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
3751 clear_bit(iommu->seq_id, &domain->iommu_bmp); 3762 clear_bit(iommu->seq_id, domain->iommu_bmp);
3752 domain->iommu_count--; 3763 domain->iommu_count--;
3753 domain_update_iommu_cap(domain); 3764 domain_update_iommu_cap(domain);
3754 spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); 3765 spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
@@ -3790,7 +3801,7 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
3790 */ 3801 */
3791 spin_lock_irqsave(&domain->iommu_lock, flags2); 3802 spin_lock_irqsave(&domain->iommu_lock, flags2);
3792 if (test_and_clear_bit(iommu->seq_id, 3803 if (test_and_clear_bit(iommu->seq_id,
3793 &domain->iommu_bmp)) { 3804 domain->iommu_bmp)) {
3794 domain->iommu_count--; 3805 domain->iommu_count--;
3795 domain_update_iommu_cap(domain); 3806 domain_update_iommu_cap(domain);
3796 } 3807 }
@@ -3815,7 +3826,7 @@ static struct dmar_domain *iommu_alloc_vm_domain(void)
3815 3826
3816 domain->id = vm_domid++; 3827 domain->id = vm_domid++;
3817 domain->nid = -1; 3828 domain->nid = -1;
3818 memset(&domain->iommu_bmp, 0, sizeof(unsigned long)); 3829 memset(domain->iommu_bmp, 0, sizeof(domain->iommu_bmp));
3819 domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE; 3830 domain->flags = DOMAIN_FLAG_VIRTUAL_MACHINE;
3820 3831
3821 return domain; 3832 return domain;