Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmar: fix using early fixmap mapping for DMAR table parsing

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>

authored by

Yinghai Lu and committed by
Ingo Molnar
f6dd5c31 a11b5abe

+28 -22
+28 -21
drivers/pci/dmar.c
··· 289 289 } 290 290 } 291 291 292 + /** 293 + * dmar_table_detect - checks to see if the platform supports DMAR devices 294 + */ 295 + static int __init dmar_table_detect(void) 296 + { 297 + acpi_status status = AE_OK; 298 + 299 + /* if we could find DMAR table, then there are DMAR devices */ 300 + status = acpi_get_table(ACPI_SIG_DMAR, 0, 301 + (struct acpi_table_header **)&dmar_tbl); 302 + 303 + if (ACPI_SUCCESS(status) && !dmar_tbl) { 304 + printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); 305 + status = AE_NOT_FOUND; 306 + } 307 + 308 + return (ACPI_SUCCESS(status) ? 1 : 0); 309 + } 292 310 293 311 /** 294 312 * parse_dmar_table - parses the DMA reporting table ··· 317 299 struct acpi_table_dmar *dmar; 318 300 struct acpi_dmar_header *entry_header; 319 301 int ret = 0; 302 + 303 + /* 304 + * Do it again, earlier dmar_tbl mapping could be mapped with 305 + * fixed map. 306 + */ 307 + dmar_table_detect(); 320 308 321 309 dmar = (struct acpi_table_dmar *)dmar_tbl; 322 310 if (!dmar) ··· 454 430 return 0; 455 431 } 456 432 457 - /** 458 - * early_dmar_detect - checks to see if the platform supports DMAR devices 459 - */ 460 - int __init early_dmar_detect(void) 461 - { 462 - acpi_status status = AE_OK; 463 - 464 - /* if we could find DMAR table, then there are DMAR devices */ 465 - status = acpi_get_table(ACPI_SIG_DMAR, 0, 466 - (struct acpi_table_header **)&dmar_tbl); 467 - 468 - if (ACPI_SUCCESS(status) && !dmar_tbl) { 469 - printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); 470 - status = AE_NOT_FOUND; 471 - } 472 - 473 - return (ACPI_SUCCESS(status) ? 1 : 0); 474 - } 475 - 476 433 void __init detect_intel_iommu(void) 477 434 { 478 435 int ret; 479 436 480 - ret = early_dmar_detect(); 437 + ret = dmar_table_detect(); 481 438 482 439 #ifdef CONFIG_DMAR 483 440 { ··· 484 479 " x2apic support\n"); 485 480 486 481 dmar_disabled = 1; 487 - return; 482 + goto end; 488 483 } 489 484 490 485 if (ret && !no_iommu && !iommu_detected && !swiotlb && 491 486 !dmar_disabled) 492 487 iommu_detected = 1; 493 488 } 489 + end: 494 490 #endif 491 + dmar_tbl = NULL; 495 492 } 496 493 497 494
-1
include/linux/dmar.h
··· 45 45 list_for_each_entry(drhd, &dmar_drhd_units, list) 46 46 47 47 extern int dmar_table_init(void); 48 - extern int early_dmar_detect(void); 49 48 extern int dmar_dev_scope_init(void); 50 49 51 50 /* Intel IOMMU detection */