diff options
| -rw-r--r-- | drivers/pci/dmar.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 56883fc1c7be..beeaef84e151 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
| @@ -613,6 +613,8 @@ int __init dmar_table_init(void) | |||
| 613 | return 0; | 613 | return 0; |
| 614 | } | 614 | } |
| 615 | 615 | ||
| 616 | static int bios_warned; | ||
| 617 | |||
| 616 | int __init check_zero_address(void) | 618 | int __init check_zero_address(void) |
| 617 | { | 619 | { |
| 618 | struct acpi_table_dmar *dmar; | 620 | struct acpi_table_dmar *dmar; |
| @@ -643,6 +645,7 @@ int __init check_zero_address(void) | |||
| 643 | dmi_get_system_info(DMI_BIOS_VENDOR), | 645 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 644 | dmi_get_system_info(DMI_BIOS_VERSION), | 646 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 645 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 647 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 648 | bios_warned = 1; | ||
| 646 | goto failed; | 649 | goto failed; |
| 647 | } | 650 | } |
| 648 | 651 | ||
| @@ -662,6 +665,7 @@ int __init check_zero_address(void) | |||
| 662 | dmi_get_system_info(DMI_BIOS_VENDOR), | 665 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 663 | dmi_get_system_info(DMI_BIOS_VERSION), | 666 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 664 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 667 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 668 | bios_warned = 1; | ||
| 665 | goto failed; | 669 | goto failed; |
| 666 | } | 670 | } |
| 667 | } | 671 | } |
| @@ -722,6 +726,18 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
| 722 | int agaw = 0; | 726 | int agaw = 0; |
| 723 | int msagaw = 0; | 727 | int msagaw = 0; |
| 724 | 728 | ||
| 729 | if (!drhd->reg_base_addr) { | ||
| 730 | if (!bios_warned) { | ||
| 731 | WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n" | ||
| 732 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | ||
| 733 | dmi_get_system_info(DMI_BIOS_VENDOR), | ||
| 734 | dmi_get_system_info(DMI_BIOS_VERSION), | ||
| 735 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
| 736 | bios_warned = 1; | ||
| 737 | } | ||
| 738 | return -EINVAL; | ||
| 739 | } | ||
| 740 | |||
| 725 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); | 741 | iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); |
| 726 | if (!iommu) | 742 | if (!iommu) |
| 727 | return -ENOMEM; | 743 | return -ENOMEM; |
| @@ -738,13 +754,16 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) | |||
| 738 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); | 754 | iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); |
| 739 | 755 | ||
| 740 | if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { | 756 | if (iommu->cap == (uint64_t)-1 && iommu->ecap == (uint64_t)-1) { |
| 741 | /* Promote an attitude of violence to a BIOS engineer today */ | 757 | if (!bios_warned) { |
| 742 | WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" | 758 | /* Promote an attitude of violence to a BIOS engineer today */ |
| 743 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", | 759 | WARN(1, "Your BIOS is broken; DMAR reported at address %llx returns all ones!\n" |
| 744 | drhd->reg_base_addr, | 760 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 745 | dmi_get_system_info(DMI_BIOS_VENDOR), | 761 | drhd->reg_base_addr, |
| 746 | dmi_get_system_info(DMI_BIOS_VERSION), | 762 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 747 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | 763 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 764 | dmi_get_system_info(DMI_PRODUCT_VERSION)); | ||
| 765 | bios_warned = 1; | ||
| 766 | } | ||
| 748 | goto err_unmap; | 767 | goto err_unmap; |
| 749 | } | 768 | } |
| 750 | 769 | ||
