dmar: fix using early fixmap mapping for DMAR table parsing
authorYinghai Lu <yhlu.kernel@gmail.com>
Wed, 3 Sep 2008 23:58:32 +0000 (16:58 -0700)
committerIngo Molnar <mingo@elte.hu>
Thu, 16 Oct 2008 14:53:04 +0000 (16:53 +0200)
Very early detection of the DMAR tables will setup fixmap mapping. For
parsing these tables later (while enabling dma and/or interrupt remapping),
early fixmap mapping shouldn't be used. Fix it by calling table detection
routines again, which will call generic apci_get_table() for setting up
the correct mapping.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
drivers/pci/dmar.c
include/linux/dmar.h

index bd2c01674f5ec1cd07063ce499e38e5faf805995..f2c5eb6e78f7c5dd58526f9ef3ef3c74fd5737ae 100644 (file)
@@ -289,6 +289,24 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
        }
 }
 
+/**
+ * dmar_table_detect - checks to see if the platform supports DMAR devices
+ */
+static int __init dmar_table_detect(void)
+{
+       acpi_status status = AE_OK;
+
+       /* if we could find DMAR table, then there are DMAR devices */
+       status = acpi_get_table(ACPI_SIG_DMAR, 0,
+                               (struct acpi_table_header **)&dmar_tbl);
+
+       if (ACPI_SUCCESS(status) && !dmar_tbl) {
+               printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
+               status = AE_NOT_FOUND;
+       }
+
+       return (ACPI_SUCCESS(status) ? 1 : 0);
+}
 
 /**
  * parse_dmar_table - parses the DMA reporting table
@@ -300,6 +318,12 @@ parse_dmar_table(void)
        struct acpi_dmar_header *entry_header;
        int ret = 0;
 
+       /*
+        * Do it again, earlier dmar_tbl mapping could be mapped with
+        * fixed map.
+        */
+       dmar_table_detect();
+
        dmar = (struct acpi_table_dmar *)dmar_tbl;
        if (!dmar)
                return -ENODEV;
@@ -430,30 +454,11 @@ int __init dmar_table_init(void)
        return 0;
 }
 
-/**
- * early_dmar_detect - checks to see if the platform supports DMAR devices
- */
-int __init early_dmar_detect(void)
-{
-       acpi_status status = AE_OK;
-
-       /* if we could find DMAR table, then there are DMAR devices */
-       status = acpi_get_table(ACPI_SIG_DMAR, 0,
-                               (struct acpi_table_header **)&dmar_tbl);
-
-       if (ACPI_SUCCESS(status) && !dmar_tbl) {
-               printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
-               status = AE_NOT_FOUND;
-       }
-
-       return (ACPI_SUCCESS(status) ? 1 : 0);
-}
-
 void __init detect_intel_iommu(void)
 {
        int ret;
 
-       ret = early_dmar_detect();
+       ret = dmar_table_detect();
 
 #ifdef CONFIG_DMAR
        {
@@ -479,14 +484,16 @@ void __init detect_intel_iommu(void)
                               " x2apic support\n");
 
                        dmar_disabled = 1;
-                       return;
+                       goto end;
                }
 
                if (ret && !no_iommu && !iommu_detected && !swiotlb &&
                    !dmar_disabled)
                        iommu_detected = 1;
        }
+end:
 #endif
+       dmar_tbl = NULL;
 }
 
 
index c360c558e59eb5b58952955e3172658ed86f8848..f1984fc3e06d54e21646c79c591169c5a3f84aeb 100644 (file)
@@ -45,7 +45,6 @@ extern struct list_head dmar_drhd_units;
        list_for_each_entry(drhd, &dmar_drhd_units, list)
 
 extern int dmar_table_init(void);
-extern int early_dmar_detect(void);
 extern int dmar_dev_scope_init(void);
 
 /* Intel IOMMU detection */