aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/dmar.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 525a32487abd..56883fc1c7be 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -632,6 +632,9 @@ int __init check_zero_address(void)
632 } 632 }
633 633
634 if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) { 634 if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
635 void __iomem *addr;
636 u64 cap, ecap;
637
635 drhd = (void *)entry_header; 638 drhd = (void *)entry_header;
636 if (!drhd->address) { 639 if (!drhd->address) {
637 /* Promote an attitude of violence to a BIOS engineer today */ 640 /* Promote an attitude of violence to a BIOS engineer today */
@@ -640,17 +643,38 @@ int __init check_zero_address(void)
640 dmi_get_system_info(DMI_BIOS_VENDOR), 643 dmi_get_system_info(DMI_BIOS_VENDOR),
641 dmi_get_system_info(DMI_BIOS_VERSION), 644 dmi_get_system_info(DMI_BIOS_VERSION),
642 dmi_get_system_info(DMI_PRODUCT_VERSION)); 645 dmi_get_system_info(DMI_PRODUCT_VERSION));
643#ifdef CONFIG_DMAR 646 goto failed;
644 dmar_disabled = 1; 647 }
645#endif 648
646 return 0; 649 addr = early_ioremap(drhd->address, VTD_PAGE_SIZE);
650 if (!addr ) {
651 printk("IOMMU: can't validate: %llx\n", drhd->address);
652 goto failed;
653 }
654 cap = dmar_readq(addr + DMAR_CAP_REG);
655 ecap = dmar_readq(addr + DMAR_ECAP_REG);
656 early_iounmap(addr, VTD_PAGE_SIZE);
657 if (cap == (uint64_t)-1 && ecap == (uint64_t)-1) {
658 /* Promote an attitude of violence to a BIOS engineer today */
659 WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n"
660 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
661 drhd->address,
662 dmi_get_system_info(DMI_BIOS_VENDOR),
663 dmi_get_system_info(DMI_BIOS_VERSION),
664 dmi_get_system_info(DMI_PRODUCT_VERSION));
665 goto failed;
647 } 666 }
648 break;
649 } 667 }
650 668
651 entry_header = ((void *)entry_header + entry_header->length); 669 entry_header = ((void *)entry_header + entry_header->length);
652 } 670 }
653 return 1; 671 return 1;
672
673failed:
674#ifdef CONFIG_DMAR
675 dmar_disabled = 1;
676#endif
677 return 0;
654} 678}
655 679
656void __init detect_intel_iommu(void) 680void __init detect_intel_iommu(void)