Skip to content

Commit

Permalink
dmar: fix using early fixmap mapping for DMAR table parsing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Yinghai Lu authored and Ingo Molnar committed Oct 16, 2008
1 parent a11b5ab commit f6dd5c3
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 22 deletions.
49 changes: 28 additions & 21 deletions drivers/pci/dmar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
{
Expand All @@ -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;
}


Expand Down
1 change: 0 additions & 1 deletion include/linux/dmar.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down

0 comments on commit f6dd5c3

Please sign in to comment.