aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/dmar.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 13:06:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 13:06:10 -0400
commitb09a75fc5e77b7c58d097236f89b1ff72dcdb562 (patch)
tree8f818f1b3e44d9bc822b13dc7c368077981dd6ea /drivers/pci/dmar.c
parentcf63ff5fa4399e215cc5ef322ccd8bddfff9afa6 (diff)
parentb94996c99c8befed9cbbb8804a4625e203913318 (diff)
Merge git://git.infradead.org/iommu-2.6
* git://git.infradead.org/iommu-2.6: (23 commits) intel-iommu: Disable PMRs after we enable translation, not before intel-iommu: Kill DMAR_BROKEN_GFX_WA option. intel-iommu: Fix integer wrap on 32 bit kernels intel-iommu: Fix integer overflow in dma_pte_{clear_range,free_pagetable}() intel-iommu: Limit DOMAIN_MAX_PFN to fit in an 'unsigned long' intel-iommu: Fix kernel hang if interrupt remapping disabled in BIOS intel-iommu: Disallow interrupt remapping if not all ioapics covered intel-iommu: include linux/dmi.h to use dmi_ routines pci/dmar: correct off-by-one error in dmar_fault() intel-iommu: Cope with yet another BIOS screwup causing crashes intel-iommu: iommu init error path bug fixes intel-iommu: Mark functions with __init USB: Work around BIOS bugs by quiescing USB controllers earlier ia64: IOMMU passthrough mode shouldn't trigger swiotlb init intel-iommu: make domain_add_dev_info() call domain_context_mapping() intel-iommu: Unify hardware and software passthrough support intel-iommu: Cope with broken HP DC7900 BIOS iommu=pt is a valid early param intel-iommu: double kfree() intel-iommu: Kill pointless intel_unmap_single() function ... Fixed up trivial include lines conflict in drivers/pci/intel-iommu.c
Diffstat (limited to 'drivers/pci/dmar.c')
-rw-r--r--drivers/pci/dmar.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 5f6b915d0d8..14bbaa17e2c 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -577,9 +577,6 @@ int __init dmar_table_init(void)
577 printk(KERN_INFO PREFIX "No ATSR found\n"); 577 printk(KERN_INFO PREFIX "No ATSR found\n");
578#endif 578#endif
579 579
580#ifdef CONFIG_INTR_REMAP
581 parse_ioapics_under_ir();
582#endif
583 return 0; 580 return 0;
584} 581}
585 582
@@ -639,20 +636,31 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
639 iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); 636 iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
640 iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); 637 iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
641 638
639 if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) {
640 /* Promote an attitude of violence to a BIOS engineer today */
641 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
642 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
643 drhd->reg_base_addr,
644 dmi_get_system_info(DMI_BIOS_VENDOR),
645 dmi_get_system_info(DMI_BIOS_VERSION),
646 dmi_get_system_info(DMI_PRODUCT_VERSION));
647 goto err_unmap;
648 }
649
642#ifdef CONFIG_DMAR 650#ifdef CONFIG_DMAR
643 agaw = iommu_calculate_agaw(iommu); 651 agaw = iommu_calculate_agaw(iommu);
644 if (agaw < 0) { 652 if (agaw < 0) {
645 printk(KERN_ERR 653 printk(KERN_ERR
646 "Cannot get a valid agaw for iommu (seq_id = %d)\n", 654 "Cannot get a valid agaw for iommu (seq_id = %d)\n",
647 iommu->seq_id); 655 iommu->seq_id);
648 goto error; 656 goto err_unmap;
649 } 657 }
650 msagaw = iommu_calculate_max_sagaw(iommu); 658 msagaw = iommu_calculate_max_sagaw(iommu);
651 if (msagaw < 0) { 659 if (msagaw < 0) {
652 printk(KERN_ERR 660 printk(KERN_ERR
653 "Cannot get a valid max agaw for iommu (seq_id = %d)\n", 661 "Cannot get a valid max agaw for iommu (seq_id = %d)\n",
654 iommu->seq_id); 662 iommu->seq_id);
655 goto error; 663 goto err_unmap;
656 } 664 }
657#endif 665#endif
658 iommu->agaw = agaw; 666 iommu->agaw = agaw;
@@ -672,7 +680,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
672 } 680 }
673 681
674 ver = readl(iommu->reg + DMAR_VER_REG); 682 ver = readl(iommu->reg + DMAR_VER_REG);
675 pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n", 683 pr_info("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
676 (unsigned long long)drhd->reg_base_addr, 684 (unsigned long long)drhd->reg_base_addr,
677 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver), 685 DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
678 (unsigned long long)iommu->cap, 686 (unsigned long long)iommu->cap,
@@ -682,7 +690,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
682 690
683 drhd->iommu = iommu; 691 drhd->iommu = iommu;
684 return 0; 692 return 0;
685error: 693
694 err_unmap:
695 iounmap(iommu->reg);
696 error:
686 kfree(iommu); 697 kfree(iommu);
687 return -1; 698 return -1;
688} 699}
@@ -1219,7 +1230,7 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
1219 source_id, guest_addr); 1230 source_id, guest_addr);
1220 1231
1221 fault_index++; 1232 fault_index++;
1222 if (fault_index > cap_num_fault_regs(iommu->cap)) 1233 if (fault_index >= cap_num_fault_regs(iommu->cap))
1223 fault_index = 0; 1234 fault_index = 0;
1224 spin_lock_irqsave(&iommu->register_lock, flag); 1235 spin_lock_irqsave(&iommu->register_lock, flag);
1225 } 1236 }
@@ -1312,3 +1323,13 @@ int dmar_reenable_qi(struct intel_iommu *iommu)
1312 1323
1313 return 0; 1324 return 0;
1314} 1325}
1326
1327/*
1328 * Check interrupt remapping support in DMAR table description.
1329 */
1330int dmar_ir_support(void)
1331{
1332 struct acpi_table_dmar *dmar;
1333 dmar = (struct acpi_table_dmar *)dmar_tbl;
1334 return dmar->flags & 0x1;
1335}