aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-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