|
@@ -33,6 +33,7 @@
|
|
|
#include <asm/gart.h>
|
|
|
#include <asm/x86_init.h>
|
|
|
#include <asm/iommu_table.h>
|
|
|
+#include <asm/io_apic.h>
|
|
|
|
|
|
#include "amd_iommu_proto.h"
|
|
|
#include "amd_iommu_types.h"
|
|
@@ -1575,6 +1576,23 @@ static void __init free_on_init_error(void)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+static bool __init check_ioapic_information(void)
|
|
|
+{
|
|
|
+ int idx;
|
|
|
+
|
|
|
+ for (idx = 0; idx < nr_ioapics; idx++) {
|
|
|
+ int id = mpc_ioapic_id(idx);
|
|
|
+
|
|
|
+ if (get_ioapic_devid(id) < 0) {
|
|
|
+ pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id);
|
|
|
+ pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This is the hardware init function for AMD IOMMU in the system.
|
|
|
* 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)
|
|
|
if (amd_iommu_pd_alloc_bitmap == NULL)
|
|
|
goto out;
|
|
|
|
|
|
- /* init the device table */
|
|
|
- init_device_table();
|
|
|
-
|
|
|
/*
|
|
|
* let all alias entries point to itself
|
|
|
*/
|
|
@@ -1686,6 +1701,9 @@ static int __init early_amd_iommu_init(void)
|
|
|
if (ret)
|
|
|
goto out;
|
|
|
|
|
|
+ if (amd_iommu_irq_remap)
|
|
|
+ amd_iommu_irq_remap = check_ioapic_information();
|
|
|
+
|
|
|
if (amd_iommu_irq_remap) {
|
|
|
/*
|
|
|
* Interrupt remapping enabled, create kmem_cache for the
|
|
@@ -1709,6 +1727,9 @@ static int __init early_amd_iommu_init(void)
|
|
|
if (ret)
|
|
|
goto out;
|
|
|
|
|
|
+ /* init the device table */
|
|
|
+ init_device_table();
|
|
|
+
|
|
|
out:
|
|
|
/* Don't leak any ACPI memory */
|
|
|
early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
|