aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/amd_iommu_init.c
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2012-07-05 05:58:02 -0400
committerJoerg Roedel <joerg.roedel@amd.com>2012-09-28 11:31:09 -0400
commiteb1eb7ae65a9d32f6c16a90419caf01221f94734 (patch)
treefd57fa0d4fe3a201882d840dc94682a7656efb6a /drivers/iommu/amd_iommu_init.c
parent0ea2c422bc8da99d14baa46d4789861a4f8d4ec0 (diff)
iommu/amd: Check if IOAPIC information is correct
When the IOAPIC information provided in the IVRS table is not correct or not complete the system may not boot at all when interrupt remapping is enabled. So check if this information is correct and print out a firmware bug message when it is not. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Diffstat (limited to 'drivers/iommu/amd_iommu_init.c')
-rw-r--r--drivers/iommu/amd_iommu_init.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 2d923fe7c2a1..f8a222b0ac3f 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -33,6 +33,7 @@
33#include <asm/gart.h> 33#include <asm/gart.h>
34#include <asm/x86_init.h> 34#include <asm/x86_init.h>
35#include <asm/iommu_table.h> 35#include <asm/iommu_table.h>
36#include <asm/io_apic.h>
36 37
37#include "amd_iommu_proto.h" 38#include "amd_iommu_proto.h"
38#include "amd_iommu_types.h" 39#include "amd_iommu_types.h"
@@ -1575,6 +1576,23 @@ static void __init free_on_init_error(void)
1575#endif 1576#endif
1576} 1577}
1577 1578
1579static bool __init check_ioapic_information(void)
1580{
1581 int idx;
1582
1583 for (idx = 0; idx < nr_ioapics; idx++) {
1584 int id = mpc_ioapic_id(idx);
1585
1586 if (get_ioapic_devid(id) < 0) {
1587 pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id);
1588 pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n");
1589 return false;
1590 }
1591 }
1592
1593 return true;
1594}
1595
1578/* 1596/*
1579 * This is the hardware init function for AMD IOMMU in the system. 1597 * This is the hardware init function for AMD IOMMU in the system.
1580 * This function is called either from amd_iommu_init or from the interrupt 1598 * This function is called either from amd_iommu_init or from the interrupt
@@ -1661,9 +1679,6 @@ static int __init early_amd_iommu_init(void)
1661 if (amd_iommu_pd_alloc_bitmap == NULL) 1679 if (amd_iommu_pd_alloc_bitmap == NULL)
1662 goto out; 1680 goto out;
1663 1681
1664 /* init the device table */
1665 init_device_table();
1666
1667 /* 1682 /*
1668 * let all alias entries point to itself 1683 * let all alias entries point to itself
1669 */ 1684 */
@@ -1686,6 +1701,9 @@ static int __init early_amd_iommu_init(void)
1686 if (ret) 1701 if (ret)
1687 goto out; 1702 goto out;
1688 1703
1704 if (amd_iommu_irq_remap)
1705 amd_iommu_irq_remap = check_ioapic_information();
1706
1689 if (amd_iommu_irq_remap) { 1707 if (amd_iommu_irq_remap) {
1690 /* 1708 /*
1691 * Interrupt remapping enabled, create kmem_cache for the 1709 * Interrupt remapping enabled, create kmem_cache for the
@@ -1709,6 +1727,9 @@ static int __init early_amd_iommu_init(void)
1709 if (ret) 1727 if (ret)
1710 goto out; 1728 goto out;
1711 1729
1730 /* init the device table */
1731 init_device_table();
1732
1712out: 1733out:
1713 /* Don't leak any ACPI memory */ 1734 /* Don't leak any ACPI memory */
1714 early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); 1735 early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);