mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
a5481280b2
commit
9a73aa81ff
|
@ -261,7 +261,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
|
|||
|
||||
struct acpi_static_rsdt {
|
||||
struct acpi_table_rsdt table;
|
||||
u32 padding[7]; /* Allow for 7 more table entries */
|
||||
u32 padding[32]; /* Allow for 32 more table entries */
|
||||
};
|
||||
|
||||
int __init get_memcfg_from_srat(void)
|
||||
|
@ -297,7 +297,7 @@ int __init get_memcfg_from_srat(void)
|
|||
}
|
||||
|
||||
rsdt = (struct acpi_table_rsdt *)
|
||||
early_ioremap(rsdp->rsdt_physical_address, sizeof(struct acpi_table_rsdt));
|
||||
early_ioremap(rsdp->rsdt_physical_address, sizeof(saved_rsdt));
|
||||
|
||||
if (!rsdt) {
|
||||
printk(KERN_WARNING
|
||||
|
@ -310,6 +310,7 @@ int __init get_memcfg_from_srat(void)
|
|||
|
||||
if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) {
|
||||
printk(KERN_WARNING "ACPI: RSDT signature incorrect\n");
|
||||
early_iounmap(rsdt, sizeof(saved_rsdt));
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
|
@ -319,37 +320,51 @@ int __init get_memcfg_from_srat(void)
|
|||
* size of RSDT) divided by the size of each entry
|
||||
* (4-byte table pointers).
|
||||
*/
|
||||
tables = (header->length - sizeof(struct acpi_table_header)) / 4;
|
||||
tables = (header->length - sizeof(struct acpi_table_header)) / sizeof(u32);
|
||||
|
||||
if (!tables)
|
||||
goto out_err;
|
||||
|
||||
memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt));
|
||||
|
||||
early_iounmap(rsdt, sizeof(saved_rsdt));
|
||||
if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) {
|
||||
printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n",
|
||||
saved_rsdt.table.header.length);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
printk("Begin SRAT table scan....\n");
|
||||
printk("Begin SRAT table scan....%d\n", tables);
|
||||
|
||||
for (i = 0; i < tables; i++) {
|
||||
for (i = 0; i < tables; i++){
|
||||
int result;
|
||||
u32 length;
|
||||
/* Map in header, then map in full table length. */
|
||||
header = (struct acpi_table_header *)
|
||||
early_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header));
|
||||
if (!header)
|
||||
break;
|
||||
|
||||
printk(KERN_INFO "ACPI: %4.4s %08lX, %04X\n",
|
||||
header->signature,
|
||||
(unsigned long)saved_rsdt.table.table_offset_entry[i],
|
||||
header->length);
|
||||
|
||||
if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4)) {
|
||||
early_iounmap(header, sizeof(struct acpi_table_header));
|
||||
continue;
|
||||
}
|
||||
|
||||
length = header->length;
|
||||
early_iounmap(header, sizeof(struct acpi_table_header));
|
||||
header = (struct acpi_table_header *)
|
||||
early_ioremap(saved_rsdt.table.table_offset_entry[i], header->length);
|
||||
early_ioremap(saved_rsdt.table.table_offset_entry[i], length);
|
||||
if (!header)
|
||||
break;
|
||||
|
||||
if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4))
|
||||
continue;
|
||||
|
||||
/* we've found the srat table. don't need to look at any more tables */
|
||||
return acpi20_parse_srat((struct acpi_table_srat *)header);
|
||||
result = acpi20_parse_srat((struct acpi_table_srat *)header);
|
||||
early_iounmap(header, length);
|
||||
return result;
|
||||
}
|
||||
out_err:
|
||||
remove_all_active_ranges();
|
||||
|
|
Loading…
Reference in New Issue