]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Yinghai Lu <yhlu.kernel@gmail.com> |
2 | Subject: dmar: fix using early fixmap mapping for DMAR table parsing | |
3 | References: fate #303948 and fate #303984 | |
4 | Patch-Mainline: queued for .28 | |
5 | Commit-ID: f12c73e7fa7ebf9ad6defee2c4fb2664e743e970 | |
6 | ||
7 | Signed-off-by: Thomas Renninger <trenn@suse.de> | |
8 | ||
9 | Very early detection of the DMAR tables will setup fixmap mapping. For | |
10 | parsing these tables later (while enabling dma and/or interrupt remapping), | |
11 | early fixmap mapping shouldn't be used. Fix it by calling table detection | |
12 | routines again, which will call generic apci_get_table() for setting up | |
13 | the correct mapping. | |
14 | ||
15 | Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> | |
16 | Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> | |
17 | Signed-off-by: Ingo Molnar <mingo@elte.hu> | |
18 | ||
19 | --- | |
20 | drivers/pci/dmar.c | 49 ++++++++++++++++++++++++++++--------------------- | |
21 | include/linux/dmar.h | 1 - | |
22 | 2 files changed, 28 insertions(+), 22 deletions(-) | |
23 | ||
24 | Index: linux-2.6.26/drivers/pci/dmar.c | |
25 | =================================================================== | |
26 | --- linux-2.6.26.orig/drivers/pci/dmar.c | |
27 | +++ linux-2.6.26/drivers/pci/dmar.c | |
28 | @@ -289,6 +289,24 @@ dmar_table_print_dmar_entry(struct acpi_ | |
29 | } | |
30 | } | |
31 | ||
32 | +/** | |
33 | + * dmar_table_detect - checks to see if the platform supports DMAR devices | |
34 | + */ | |
35 | +static int __init dmar_table_detect(void) | |
36 | +{ | |
37 | + acpi_status status = AE_OK; | |
38 | + | |
39 | + /* if we could find DMAR table, then there are DMAR devices */ | |
40 | + status = acpi_get_table(ACPI_SIG_DMAR, 0, | |
41 | + (struct acpi_table_header **)&dmar_tbl); | |
42 | + | |
43 | + if (ACPI_SUCCESS(status) && !dmar_tbl) { | |
44 | + printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); | |
45 | + status = AE_NOT_FOUND; | |
46 | + } | |
47 | + | |
48 | + return (ACPI_SUCCESS(status) ? 1 : 0); | |
49 | +} | |
50 | ||
51 | /** | |
52 | * parse_dmar_table - parses the DMA reporting table | |
53 | @@ -300,6 +318,12 @@ parse_dmar_table(void) | |
54 | struct acpi_dmar_header *entry_header; | |
55 | int ret = 0; | |
56 | ||
57 | + /* | |
58 | + * Do it again, earlier dmar_tbl mapping could be mapped with | |
59 | + * fixed map. | |
60 | + */ | |
61 | + dmar_table_detect(); | |
62 | + | |
63 | dmar = (struct acpi_table_dmar *)dmar_tbl; | |
64 | if (!dmar) | |
65 | return -ENODEV; | |
66 | @@ -432,30 +456,11 @@ int __init dmar_table_init(void) | |
67 | return 0; | |
68 | } | |
69 | ||
70 | -/** | |
71 | - * early_dmar_detect - checks to see if the platform supports DMAR devices | |
72 | - */ | |
73 | -int __init early_dmar_detect(void) | |
74 | -{ | |
75 | - acpi_status status = AE_OK; | |
76 | - | |
77 | - /* if we could find DMAR table, then there are DMAR devices */ | |
78 | - status = acpi_get_table(ACPI_SIG_DMAR, 0, | |
79 | - (struct acpi_table_header **)&dmar_tbl); | |
80 | - | |
81 | - if (ACPI_SUCCESS(status) && !dmar_tbl) { | |
82 | - printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); | |
83 | - status = AE_NOT_FOUND; | |
84 | - } | |
85 | - | |
86 | - return (ACPI_SUCCESS(status) ? 1 : 0); | |
87 | -} | |
88 | - | |
89 | void __init detect_intel_iommu(void) | |
90 | { | |
91 | int ret; | |
92 | ||
93 | - ret = early_dmar_detect(); | |
94 | + ret = dmar_table_detect(); | |
95 | ||
96 | #ifdef CONFIG_DMAR | |
97 | { | |
98 | @@ -481,14 +486,16 @@ void __init detect_intel_iommu(void) | |
99 | " x2apic support\n"); | |
100 | ||
101 | dmar_disabled = 1; | |
102 | - return; | |
103 | + goto end; | |
104 | } | |
105 | ||
106 | if (ret && !no_iommu && !iommu_detected && !swiotlb && | |
107 | !dmar_disabled) | |
108 | iommu_detected = 1; | |
109 | } | |
110 | +end: | |
111 | #endif | |
112 | + dmar_tbl = NULL; | |
113 | } | |
114 | ||
115 | ||
116 | Index: linux-2.6.26/include/linux/dmar.h | |
117 | =================================================================== | |
118 | --- linux-2.6.26.orig/include/linux/dmar.h | |
119 | +++ linux-2.6.26/include/linux/dmar.h | |
120 | @@ -45,7 +45,6 @@ extern struct list_head dmar_drhd_units; | |
121 | list_for_each_entry(drhd, &dmar_drhd_units, list) | |
122 | ||
123 | extern int dmar_table_init(void); | |
124 | -extern int early_dmar_detect(void); | |
125 | extern int dmar_dev_scope_init(void); | |
126 | ||
127 | /* Intel IOMMU detection */ |