Reject SRAT tables that don't cover all memory Broken BIOS on Iwill reports these and it causes the bootmem allocator to crash. Add a sanity check if all the PXMs in the SRAT table cover all memory as reported by e820. Signed-off-by: Andi Kleen Index: linux/arch/x86_64/mm/srat.c =================================================================== --- linux.orig/arch/x86_64/mm/srat.c +++ linux/arch/x86_64/mm/srat.c @@ -17,6 +17,7 @@ #include #include #include +#include static struct acpi_table_slit *acpi_slit; @@ -196,12 +197,39 @@ acpi_numa_memory_affinity_init(struct ac nd->start, nd->end); } +/* Sanity check to catch more bad SRATs (they are amazingly common). + Make sure the PXMs cover all memory. */ +static int nodes_cover_memory(void) +{ + int i; + unsigned long pxmram, e820ram; + + pxmram = 0; + for_each_node_mask(i, nodes_parsed) { + unsigned long s = nodes[i].start >> PAGE_SHIFT; + unsigned long e = nodes[i].end >> PAGE_SHIFT; + pxmram += e - s; + pxmram -= e820_hole_size(s, e); + } + + e820ram = end_pfn - e820_hole_size(0, end_pfn); + if (pxmram < e820ram) { + printk(KERN_ERR + "SRAT: PXMs only cover %luMB of your %luMB e820 RAM. Not used.\n", + (pxmram << PAGE_SHIFT) >> 20, + (e820ram << PAGE_SHIFT) >> 20); + return 0; + } + return 1; +} + void __init acpi_numa_arch_fixup(void) {} /* Use the information discovered above to actually set up the nodes. */ int __init acpi_scan_nodes(unsigned long start, unsigned long end) { int i; + if (acpi_numa <= 0) return -1; @@ -212,6 +240,11 @@ int __init acpi_scan_nodes(unsigned long node_clear(i, nodes_parsed); } + if (!nodes_cover_memory()) { + bad_srat(); + return -1; + } + memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed)); if (memnode_shift < 0) { printk(KERN_ERR