]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.arch/x2APIC_PATCH_03_of_41_1886e8a90a580f3ad343f2065c84c1b9e1dac9ef
Revert "Disable build of xen kernel."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.arch / x2APIC_PATCH_03_of_41_1886e8a90a580f3ad343f2065c84c1b9e1dac9ef
1 From: Suresh Siddha <suresh.b.siddha@intel.com>
2 Subject: x64, x2apic/intr-remap: code re-structuring, to be used by both DMA and Interrupt remapping
3 References: fate #303948 and fate #303984
4 Patch-Mainline: queued for .28
5 Commit-ID: 1886e8a90a580f3ad343f2065c84c1b9e1dac9ef
6
7 Signed-off-by: Thomas Renninger <trenn@suse.de>
8
9 Allocate the iommu during the parse of DMA remapping hardware
10 definition structures. And also, introduce routines for device
11 scope initialization which will be explicitly called during
12 dma-remapping initialization.
13
14 These will be used for enabling interrupt remapping separately from the
15 existing DMA-remapping enabling sequence.
16
17 Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
18 Cc: akpm@linux-foundation.org
19 Cc: arjan@linux.intel.com
20 Cc: andi@firstfloor.org
21 Cc: ebiederm@xmission.com
22 Cc: jbarnes@virtuousgeek.org
23 Cc: steiner@sgi.com
24 Signed-off-by: Ingo Molnar <mingo@elte.hu>
25
26 ---
27 drivers/pci/dmar.c | 89 +++++++++++++++++++++++++++++++++++++---------
28 drivers/pci/intel-iommu.c | 10 ++---
29 drivers/pci/intel-iommu.h | 2 -
30 include/linux/dmar.h | 10 ++++-
31 4 files changed, 88 insertions(+), 23 deletions(-)
32
33 --- a/drivers/pci/dmar.c
34 +++ b/drivers/pci/dmar.c
35 @@ -174,19 +174,37 @@ dmar_parse_one_drhd(struct acpi_dmar_hea
36 struct acpi_dmar_hardware_unit *drhd;
37 struct dmar_drhd_unit *dmaru;
38 int ret = 0;
39 - static int include_all;
40
41 dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
42 if (!dmaru)
43 return -ENOMEM;
44
45 + dmaru->hdr = header;
46 drhd = (struct acpi_dmar_hardware_unit *)header;
47 dmaru->reg_base_addr = drhd->address;
48 dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
49
50 + ret = alloc_iommu(dmaru);
51 + if (ret) {
52 + kfree(dmaru);
53 + return ret;
54 + }
55 + dmar_register_drhd_unit(dmaru);
56 + return 0;
57 +}
58 +
59 +static int __init
60 +dmar_parse_dev(struct dmar_drhd_unit *dmaru)
61 +{
62 + struct acpi_dmar_hardware_unit *drhd;
63 + static int include_all;
64 + int ret;
65 +
66 + drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr;
67 +
68 if (!dmaru->include_all)
69 ret = dmar_parse_dev_scope((void *)(drhd + 1),
70 - ((void *)drhd) + header->length,
71 + ((void *)drhd) + drhd->header.length,
72 &dmaru->devices_cnt, &dmaru->devices,
73 drhd->segment);
74 else {
75 @@ -199,10 +217,10 @@ dmar_parse_one_drhd(struct acpi_dmar_hea
76 include_all = 1;
77 }
78
79 - if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all))
80 + if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) {
81 + list_del(&dmaru->list);
82 kfree(dmaru);
83 - else
84 - dmar_register_drhd_unit(dmaru);
85 + }
86 return ret;
87 }
88
89 @@ -211,23 +229,35 @@ dmar_parse_one_rmrr(struct acpi_dmar_hea
90 {
91 struct acpi_dmar_reserved_memory *rmrr;
92 struct dmar_rmrr_unit *rmrru;
93 - int ret = 0;
94
95 rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
96 if (!rmrru)
97 return -ENOMEM;
98
99 + rmrru->hdr = header;
100 rmrr = (struct acpi_dmar_reserved_memory *)header;
101 rmrru->base_address = rmrr->base_address;
102 rmrru->end_address = rmrr->end_address;
103 +
104 + dmar_register_rmrr_unit(rmrru);
105 + return 0;
106 +}
107 +
108 +static int __init
109 +rmrr_parse_dev(struct dmar_rmrr_unit *rmrru)
110 +{
111 + struct acpi_dmar_reserved_memory *rmrr;
112 + int ret;
113 +
114 + rmrr = (struct acpi_dmar_reserved_memory *) rmrru->hdr;
115 ret = dmar_parse_dev_scope((void *)(rmrr + 1),
116 - ((void *)rmrr) + header->length,
117 + ((void *)rmrr) + rmrr->header.length,
118 &rmrru->devices_cnt, &rmrru->devices, rmrr->segment);
119
120 - if (ret || (rmrru->devices_cnt == 0))
121 + if (ret || (rmrru->devices_cnt == 0)) {
122 + list_del(&rmrru->list);
123 kfree(rmrru);
124 - else
125 - dmar_register_rmrr_unit(rmrru);
126 + }
127 return ret;
128 }
129
130 @@ -333,15 +363,42 @@ dmar_find_matched_drhd_unit(struct pci_d
131 return NULL;
132 }
133
134 +int __init dmar_dev_scope_init(void)
135 +{
136 + struct dmar_drhd_unit *drhd;
137 + struct dmar_rmrr_unit *rmrr;
138 + int ret = -ENODEV;
139 +
140 + for_each_drhd_unit(drhd) {
141 + ret = dmar_parse_dev(drhd);
142 + if (ret)
143 + return ret;
144 + }
145 +
146 + for_each_rmrr_units(rmrr) {
147 + ret = rmrr_parse_dev(rmrr);
148 + if (ret)
149 + return ret;
150 + }
151 +
152 + return ret;
153 +}
154 +
155
156 int __init dmar_table_init(void)
157 {
158 -
159 + static int dmar_table_initialized;
160 int ret;
161
162 + if (dmar_table_initialized)
163 + return 0;
164 +
165 + dmar_table_initialized = 1;
166 +
167 ret = parse_dmar_table();
168 if (ret) {
169 - printk(KERN_INFO PREFIX "parse DMAR table failure.\n");
170 + if (ret != -ENODEV)
171 + printk(KERN_INFO PREFIX "parse DMAR table failure.\n");
172 return ret;
173 }
174
175 @@ -375,7 +432,7 @@ int __init early_dmar_detect(void)
176 return (ACPI_SUCCESS(status) ? 1 : 0);
177 }
178
179 -struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
180 +int alloc_iommu(struct dmar_drhd_unit *drhd)
181 {
182 struct intel_iommu *iommu;
183 int map_size;
184 @@ -384,7 +441,7 @@ struct intel_iommu *alloc_iommu(struct d
185
186 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
187 if (!iommu)
188 - return NULL;
189 + return -ENOMEM;
190
191 iommu->seq_id = iommu_allocated++;
192
193 @@ -417,10 +474,10 @@ struct intel_iommu *alloc_iommu(struct d
194 spin_lock_init(&iommu->register_lock);
195
196 drhd->iommu = iommu;
197 - return iommu;
198 + return 0;
199 error:
200 kfree(iommu);
201 - return NULL;
202 + return -1;
203 }
204
205 void free_iommu(struct intel_iommu *iommu)
206 --- a/drivers/pci/intel-iommu.c
207 +++ b/drivers/pci/intel-iommu.c
208 @@ -1667,11 +1667,8 @@ int __init init_dmars(void)
209 for_each_drhd_unit(drhd) {
210 if (drhd->ignored)
211 continue;
212 - iommu = alloc_iommu(drhd);
213 - if (!iommu) {
214 - ret = -ENOMEM;
215 - goto error;
216 - }
217 +
218 + iommu = drhd->iommu;
219
220 ret = iommu_init_domains(iommu);
221 if (ret)
222 @@ -2349,6 +2346,9 @@ int __init intel_iommu_init(void)
223 if (dmar_table_init())
224 return -ENODEV;
225
226 + if (dmar_dev_scope_init())
227 + return -ENODEV;
228 +
229 iommu_init_mempool();
230 dmar_init_reserved_ranges();
231
232 --- a/drivers/pci/intel-iommu.h
233 +++ b/drivers/pci/intel-iommu.h
234 @@ -199,7 +199,7 @@ struct intel_iommu {
235
236 extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev);
237
238 -extern struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd);
239 +extern int alloc_iommu(struct dmar_drhd_unit *drhd);
240 extern void free_iommu(struct intel_iommu *iommu);
241
242 #endif
243 --- a/include/linux/dmar.h
244 +++ b/include/linux/dmar.h
245 @@ -46,12 +46,14 @@ extern int intel_iommu_init(void);
246
247 extern int dmar_table_init(void);
248 extern int early_dmar_detect(void);
249 +extern int dmar_dev_scope_init(void);
250
251 extern struct list_head dmar_drhd_units;
252 extern struct list_head dmar_rmrr_units;
253
254 struct dmar_drhd_unit {
255 struct list_head list; /* list of drhd units */
256 + struct acpi_dmar_header *hdr; /* ACPI header */
257 u64 reg_base_addr; /* register base address*/
258 struct pci_dev **devices; /* target device array */
259 int devices_cnt; /* target device count */
260 @@ -62,6 +64,7 @@ struct dmar_drhd_unit {
261
262 struct dmar_rmrr_unit {
263 struct list_head list; /* list of rmrr units */
264 + struct acpi_dmar_header *hdr; /* ACPI header */
265 u64 base_address; /* reserved base address*/
266 u64 end_address; /* reserved end address */
267 struct pci_dev **devices; /* target devices */
268 @@ -72,6 +75,8 @@ struct dmar_rmrr_unit {
269 list_for_each_entry(drhd, &dmar_drhd_units, list)
270 #define for_each_rmrr_units(rmrr) \
271 list_for_each_entry(rmrr, &dmar_rmrr_units, list)
272 +
273 +extern int alloc_iommu(struct dmar_drhd_unit *);
274 #else
275 static inline void detect_intel_iommu(void)
276 {
277 @@ -81,6 +86,9 @@ static inline int intel_iommu_init(void)
278 {
279 return -ENODEV;
280 }
281 -
282 +static inline int dmar_table_init(void)
283 +{
284 + return -ENODEV;
285 +}
286 #endif /* !CONFIG_DMAR */
287 #endif /* __DMAR_H__ */