diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/dmar.c | 34 |
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 | |||
673 | failed: | ||
674 | #ifdef CONFIG_DMAR | ||
675 | dmar_disabled = 1; | ||
676 | #endif | ||
677 | return 0; | ||
654 | } | 678 | } |
655 | 679 | ||
656 | void __init detect_intel_iommu(void) | 680 | void __init detect_intel_iommu(void) |