aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/e820.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/e820.c')
-rw-r--r--arch/x86_64/kernel/e820.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index d6d7f731f6f0..708a3cd9a27e 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/kexec.h> 17#include <linux/kexec.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/mm.h>
19 20
20#include <asm/pgtable.h> 21#include <asm/pgtable.h>
21#include <asm/page.h> 22#include <asm/page.h>
@@ -297,6 +298,53 @@ void __init e820_reserve_resources(void)
297 } 298 }
298} 299}
299 300
301/* Mark pages corresponding to given address range as nosave */
302static void __init
303e820_mark_nosave_range(unsigned long start, unsigned long end)
304{
305 unsigned long pfn, max_pfn;
306
307 if (start >= end)
308 return;
309
310 printk("Nosave address range: %016lx - %016lx\n", start, end);
311 max_pfn = end >> PAGE_SHIFT;
312 for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++)
313 if (pfn_valid(pfn))
314 SetPageNosave(pfn_to_page(pfn));
315}
316
317/*
318 * Find the ranges of physical addresses that do not correspond to
319 * e820 RAM areas and mark the corresponding pages as nosave for software
320 * suspend and suspend to RAM.
321 *
322 * This function requires the e820 map to be sorted and without any
323 * overlapping entries and assumes the first e820 area to be RAM.
324 */
325void __init e820_mark_nosave_regions(void)
326{
327 int i;
328 unsigned long paddr;
329
330 paddr = round_down(e820.map[0].addr + e820.map[0].size, PAGE_SIZE);
331 for (i = 1; i < e820.nr_map; i++) {
332 struct e820entry *ei = &e820.map[i];
333
334 if (paddr < ei->addr)
335 e820_mark_nosave_range(paddr,
336 round_up(ei->addr, PAGE_SIZE));
337
338 paddr = round_down(ei->addr + ei->size, PAGE_SIZE);
339 if (ei->type != E820_RAM)
340 e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE),
341 paddr);
342
343 if (paddr >= (end_pfn << PAGE_SHIFT))
344 break;
345 }
346}
347
300/* 348/*
301 * Add a memory region to the kernel e820 map. 349 * Add a memory region to the kernel e820 map.
302 */ 350 */