aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-01-11 16:44:39 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-11 22:04:55 -0500
commit8a6fdd3e912e0ce6f723431d66baf704bf8a1d26 (patch)
tree930056ca5dc50ce6245cd602f044e224dd5a8776
parent95833c83f3b812c78e48db4eaa19f6c74958470b (diff)
[PATCH] x86_64: Reject SRAT tables that don't cover all memory
Broken BIOS on Iwill 8way systems 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. If the sanity check fails the SRAT is rejected and the code will fall back to discover the NUMA topology using the K8 northbridge registers when applicable. Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/x86_64/mm/srat.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index d96c701dbed6..8b7f85608fa8 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -17,6 +17,7 @@
17#include <linux/topology.h> 17#include <linux/topology.h>
18#include <asm/proto.h> 18#include <asm/proto.h>
19#include <asm/numa.h> 19#include <asm/numa.h>
20#include <asm/e820.h>
20 21
21static struct acpi_table_slit *acpi_slit; 22static struct acpi_table_slit *acpi_slit;
22 23
@@ -196,12 +197,39 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
196 nd->start, nd->end); 197 nd->start, nd->end);
197} 198}
198 199
200/* Sanity check to catch more bad SRATs (they are amazingly common).
201 Make sure the PXMs cover all memory. */
202static int nodes_cover_memory(void)
203{
204 int i;
205 unsigned long pxmram, e820ram;
206
207 pxmram = 0;
208 for_each_node_mask(i, nodes_parsed) {
209 unsigned long s = nodes[i].start >> PAGE_SHIFT;
210 unsigned long e = nodes[i].end >> PAGE_SHIFT;
211 pxmram += e - s;
212 pxmram -= e820_hole_size(s, e);
213 }
214
215 e820ram = end_pfn - e820_hole_size(0, end_pfn);
216 if (pxmram < e820ram) {
217 printk(KERN_ERR
218 "SRAT: PXMs only cover %luMB of your %luMB e820 RAM. Not used.\n",
219 (pxmram << PAGE_SHIFT) >> 20,
220 (e820ram << PAGE_SHIFT) >> 20);
221 return 0;
222 }
223 return 1;
224}
225
199void __init acpi_numa_arch_fixup(void) {} 226void __init acpi_numa_arch_fixup(void) {}
200 227
201/* Use the information discovered above to actually set up the nodes. */ 228/* Use the information discovered above to actually set up the nodes. */
202int __init acpi_scan_nodes(unsigned long start, unsigned long end) 229int __init acpi_scan_nodes(unsigned long start, unsigned long end)
203{ 230{
204 int i; 231 int i;
232
205 if (acpi_numa <= 0) 233 if (acpi_numa <= 0)
206 return -1; 234 return -1;
207 235
@@ -212,6 +240,11 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
212 node_clear(i, nodes_parsed); 240 node_clear(i, nodes_parsed);
213 } 241 }
214 242
243 if (!nodes_cover_memory()) {
244 bad_srat();
245 return -1;
246 }
247
215 memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed)); 248 memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed));
216 if (memnode_shift < 0) { 249 if (memnode_shift < 0) {
217 printk(KERN_ERR 250 printk(KERN_ERR