aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/e820.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 13c6c37610e0..2570643ba1c5 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -289,47 +289,61 @@ void __init e820_mark_nosave_regions(void)
289 } 289 }
290} 290}
291 291
292/* Walk the e820 map and register active regions within a node */ 292/*
293void __init 293 * Finds an active region in the address range from start_pfn to end_pfn and
294e820_register_active_regions(int nid, unsigned long start_pfn, 294 * returns its range in ei_startpfn and ei_endpfn for the e820 entry.
295 unsigned long end_pfn) 295 */
296static int __init e820_find_active_region(const struct e820entry *ei,
297 unsigned long start_pfn,
298 unsigned long end_pfn,
299 unsigned long *ei_startpfn,
300 unsigned long *ei_endpfn)
296{ 301{
297 int i; 302 *ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
298 unsigned long ei_startpfn, ei_endpfn; 303 *ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) >> PAGE_SHIFT;
299 for (i = 0; i < e820.nr_map; i++) {
300 struct e820entry *ei = &e820.map[i];
301 ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
302 ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE)
303 >> PAGE_SHIFT;
304 304
305 /* Skip map entries smaller than a page */ 305 /* Skip map entries smaller than a page */
306 if (ei_startpfn >= ei_endpfn) 306 if (*ei_startpfn >= *ei_endpfn)
307 continue; 307 return 0;
308 308
309 /* Check if end_pfn_map should be updated */ 309 /* Check if end_pfn_map should be updated */
310 if (ei->type != E820_RAM && ei_endpfn > end_pfn_map) 310 if (ei->type != E820_RAM && *ei_endpfn > end_pfn_map)
311 end_pfn_map = ei_endpfn; 311 end_pfn_map = *ei_endpfn;
312 312
313 /* Skip if map is outside the node */ 313 /* Skip if map is outside the node */
314 if (ei->type != E820_RAM || 314 if (ei->type != E820_RAM || *ei_endpfn <= start_pfn ||
315 ei_endpfn <= start_pfn || 315 *ei_startpfn >= end_pfn)
316 ei_startpfn >= end_pfn) 316 return 0;
317 continue;
318 317
319 /* Check for overlaps */ 318 /* Check for overlaps */
320 if (ei_startpfn < start_pfn) 319 if (*ei_startpfn < start_pfn)
321 ei_startpfn = start_pfn; 320 *ei_startpfn = start_pfn;
322 if (ei_endpfn > end_pfn) 321 if (*ei_endpfn > end_pfn)
323 ei_endpfn = end_pfn; 322 *ei_endpfn = end_pfn;
324 323
325 /* Obey end_user_pfn to save on memmap */ 324 /* Obey end_user_pfn to save on memmap */
326 if (ei_startpfn >= end_user_pfn) 325 if (*ei_startpfn >= end_user_pfn)
327 continue; 326 return 0;
328 if (ei_endpfn > end_user_pfn) 327 if (*ei_endpfn > end_user_pfn)
329 ei_endpfn = end_user_pfn; 328 *ei_endpfn = end_user_pfn;
330 329
331 add_active_range(nid, ei_startpfn, ei_endpfn); 330 return 1;
332 } 331}
332
333/* Walk the e820 map and register active regions within a node */
334void __init
335e820_register_active_regions(int nid, unsigned long start_pfn,
336 unsigned long end_pfn)
337{
338 unsigned long ei_startpfn;
339 unsigned long ei_endpfn;
340 int i;
341
342 for (i = 0; i < e820.nr_map; i++)
343 if (e820_find_active_region(&e820.map[i],
344 start_pfn, end_pfn,
345 &ei_startpfn, &ei_endpfn))
346 add_active_range(nid, ei_startpfn, ei_endpfn);
333} 347}
334 348
335/* 349/*