aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/srat_32.c
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-05-29 19:25:56 -0400
committerIngo Molnar <mingo@elte.hu>2008-05-31 03:55:56 -0400
commit9a73aa81ffb993382afed2ed404bc2b330d75427 (patch)
treef2dcd6078bf711e2ba5731dbd7e2afbb498519dc /arch/x86/kernel/srat_32.c
parenta5481280b29b6a3db912ec100498bd31eaa6d2db (diff)
x86: 32bit numa srat fix early_ioremap leak
on two node system (16g RAM) with numa config I got this crash: get_memcfg_from_srat: assigning address to rsdp RSD PTR v0 [ACPIAM] ACPI: Too big length in RSDT: 92 failed to get NUMA memory information from SRAT table NUMA - single node, flat memory mode Node: 0, start_pfn: 0, end_pfn: 153 Setting physnode_map array to node 0 for pfns: 0 ... Pid: 0, comm: swapper Not tainted 2.6.26-rc4 #4 [<80b41289>] hlt_loop+0x0/0x3 [<8011efa0>] ? alloc_remap+0x50/0x70 [<8079e32e>] alloc_node_mem_map+0x5e/0xa0 [<8012e77b>] ? printk+0x1b/0x20 [<80b590f6>] free_area_init_node+0xc6/0x470 [<80b588fc>] ? __alloc_bootmem_node+0x2c/0x50 [<80b58ad8>] ? find_min_pfn_for_node+0x38/0x70 [<8012e77b>] ? printk+0x1b/0x20 [<80b597c4>] free_area_init_nodes+0x254/0x2d0 [<80b544d7>] zone_sizes_init+0x97/0xa0 [<80b48a03>] setup_arch+0x383/0x530 [<8012e77b>] ? printk+0x1b/0x20 [<80b41aa4>] start_kernel+0x64/0x350 [<80b412d8>] i386_start_kernel+0x8/0x10 ======================= this patch increases the acpi table limit to 32. Also match early_ioremap() with early_iounmap(). Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/srat_32.c')
-rw-r--r--arch/x86/kernel/srat_32.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/arch/x86/kernel/srat_32.c b/arch/x86/kernel/srat_32.c
index 70e4a374b4e8..88971ee166d4 100644
--- a/arch/x86/kernel/srat_32.c
+++ b/arch/x86/kernel/srat_32.c
@@ -261,7 +261,7 @@ out_fail:
261 261
262struct acpi_static_rsdt { 262struct acpi_static_rsdt {
263 struct acpi_table_rsdt table; 263 struct acpi_table_rsdt table;
264 u32 padding[7]; /* Allow for 7 more table entries */ 264 u32 padding[32]; /* Allow for 32 more table entries */
265}; 265};
266 266
267int __init get_memcfg_from_srat(void) 267int __init get_memcfg_from_srat(void)
@@ -297,7 +297,7 @@ int __init get_memcfg_from_srat(void)
297 } 297 }
298 298
299 rsdt = (struct acpi_table_rsdt *) 299 rsdt = (struct acpi_table_rsdt *)
300 early_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt)); 300 early_ioremap(rsdp->rsdt_physical_address, sizeof(saved_rsdt));
301 301
302 if (!rsdt) { 302 if (!rsdt) {
303 printk(KERN_WARNING 303 printk(KERN_WARNING
@@ -310,6 +310,7 @@ int __init get_memcfg_from_srat(void)
310 310
311 if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) { 311 if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) {
312 printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); 312 printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
313 early_iounmap(rsdt, sizeof(saved_rsdt));
313 goto out_err; 314 goto out_err;
314 } 315 }
315 316
@@ -319,37 +320,51 @@ int __init get_memcfg_from_srat(void)
319 * size of RSDT) divided by the size of each entry 320 * size of RSDT) divided by the size of each entry
320 * (4-byte table pointers). 321 * (4-byte table pointers).
321 */ 322 */
322 tables = (header->length - sizeof(struct acpi_table_header)) / 4; 323 tables = (header->length - sizeof(struct acpi_table_header)) / sizeof(u32);
323 324
324 if (!tables) 325 if (!tables)
325 goto out_err; 326 goto out_err;
326 327
327 memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); 328 memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
328 329 early_iounmap(rsdt, sizeof(saved_rsdt));
329 if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) { 330 if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) {
330 printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", 331 printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n",
331 saved_rsdt.table.header.length); 332 saved_rsdt.table.header.length);
332 goto out_err; 333 goto out_err;
333 } 334 }
334 335
335 printk("Begin SRAT table scan....\n"); 336 printk("Begin SRAT table scan....%d\n", tables);
336 337
337 for (i = 0; i < tables; i++) { 338 for (i = 0; i < tables; i++){
339 int result;
340 u32 length;
338 /* Map in header, then map in full table length. */ 341 /* Map in header, then map in full table length. */
339 header = (struct acpi_table_header *) 342 header = (struct acpi_table_header *)
340 early_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header)); 343 early_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header));
341 if (!header) 344 if (!header)
342 break; 345 break;
346
347 printk(KERN_INFO "ACPI: %4.4s %08lX, %04X\n",
348 header->signature,
349 (unsigned long)saved_rsdt.table.table_offset_entry[i],
350 header->length);
351
352 if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4)) {
353 early_iounmap(header, sizeof(struct acpi_table_header));
354 continue;
355 }
356
357 length = header->length;
358 early_iounmap(header, sizeof(struct acpi_table_header));
343 header = (struct acpi_table_header *) 359 header = (struct acpi_table_header *)
344 early_ioremap(saved_rsdt.table.table_offset_entry[i], header->length); 360 early_ioremap(saved_rsdt.table.table_offset_entry[i], length);
345 if (!header) 361 if (!header)
346 break; 362 break;
347 363
348 if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4))
349 continue;
350
351 /* we've found the srat table. don't need to look at any more tables */ 364 /* we've found the srat table. don't need to look at any more tables */
352 return acpi20_parse_srat((struct acpi_table_srat *)header); 365 result = acpi20_parse_srat((struct acpi_table_srat *)header);
366 early_iounmap(header, length);
367 return result;
353 } 368 }
354out_err: 369out_err:
355 remove_all_active_ranges(); 370 remove_all_active_ranges();