diff options
-rw-r--r-- | arch/x86/kernel/e820.c | 32 | ||||
-rw-r--r-- | arch/x86/kernel/e820_32.c | 32 | ||||
-rw-r--r-- | arch/x86/kernel/e820_64.c | 32 | ||||
-rw-r--r-- | arch/x86/kernel/setup_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 2 | ||||
-rw-r--r-- | include/asm-x86/e820.h | 9 | ||||
-rw-r--r-- | include/asm-x86/e820_32.h | 8 | ||||
-rw-r--r-- | include/asm-x86/e820_64.h | 1 |
8 files changed, 43 insertions, 75 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 35da8cdbe5e6..0cd9132c9450 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
21 | #include <linux/suspend.h> | ||
21 | 22 | ||
22 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
23 | #include <asm/page.h> | 24 | #include <asm/page.h> |
@@ -495,6 +496,37 @@ __init void e820_setup_gap(void) | |||
495 | pci_mem_start, gapstart, gapsize); | 496 | pci_mem_start, gapstart, gapsize); |
496 | } | 497 | } |
497 | 498 | ||
499 | #if defined(CONFIG_X86_64) || \ | ||
500 | (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) | ||
501 | /** | ||
502 | * Find the ranges of physical addresses that do not correspond to | ||
503 | * e820 RAM areas and mark the corresponding pages as nosave for | ||
504 | * hibernation (32 bit) or software suspend and suspend to RAM (64 bit). | ||
505 | * | ||
506 | * This function requires the e820 map to be sorted and without any | ||
507 | * overlapping entries and assumes the first e820 area to be RAM. | ||
508 | */ | ||
509 | void __init e820_mark_nosave_regions(unsigned long limit_pfn) | ||
510 | { | ||
511 | int i; | ||
512 | unsigned long pfn; | ||
513 | |||
514 | pfn = PFN_DOWN(e820.map[0].addr + e820.map[0].size); | ||
515 | for (i = 1; i < e820.nr_map; i++) { | ||
516 | struct e820entry *ei = &e820.map[i]; | ||
517 | |||
518 | if (pfn < PFN_UP(ei->addr)) | ||
519 | register_nosave_region(pfn, PFN_UP(ei->addr)); | ||
520 | |||
521 | pfn = PFN_DOWN(ei->addr + ei->size); | ||
522 | if (ei->type != E820_RAM) | ||
523 | register_nosave_region(PFN_UP(ei->addr), pfn); | ||
524 | |||
525 | if (pfn >= limit_pfn) | ||
526 | break; | ||
527 | } | ||
528 | } | ||
529 | #endif | ||
498 | 530 | ||
499 | /* | 531 | /* |
500 | * Early reserved memory areas. | 532 | * Early reserved memory areas. |
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index dfe25751038b..db760d4706af 100644 --- a/arch/x86/kernel/e820_32.c +++ b/arch/x86/kernel/e820_32.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/pfn.h> | 10 | #include <linux/pfn.h> |
11 | #include <linux/uaccess.h> | 11 | #include <linux/uaccess.h> |
12 | #include <linux/suspend.h> | ||
13 | 12 | ||
14 | #include <asm/pgtable.h> | 13 | #include <asm/pgtable.h> |
15 | #include <asm/page.h> | 14 | #include <asm/page.h> |
@@ -208,37 +207,6 @@ void __init init_iomem_resources(struct resource *code_resource, | |||
208 | } | 207 | } |
209 | } | 208 | } |
210 | 209 | ||
211 | #if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION) | ||
212 | /** | ||
213 | * e820_mark_nosave_regions - Find the ranges of physical addresses that do not | ||
214 | * correspond to e820 RAM areas and mark the corresponding pages as nosave for | ||
215 | * hibernation. | ||
216 | * | ||
217 | * This function requires the e820 map to be sorted and without any | ||
218 | * overlapping entries and assumes the first e820 area to be RAM. | ||
219 | */ | ||
220 | void __init e820_mark_nosave_regions(void) | ||
221 | { | ||
222 | int i; | ||
223 | unsigned long pfn; | ||
224 | |||
225 | pfn = PFN_DOWN(e820.map[0].addr + e820.map[0].size); | ||
226 | for (i = 1; i < e820.nr_map; i++) { | ||
227 | struct e820entry *ei = &e820.map[i]; | ||
228 | |||
229 | if (pfn < PFN_UP(ei->addr)) | ||
230 | register_nosave_region(pfn, PFN_UP(ei->addr)); | ||
231 | |||
232 | pfn = PFN_DOWN(ei->addr + ei->size); | ||
233 | if (ei->type != E820_RAM) | ||
234 | register_nosave_region(PFN_UP(ei->addr), pfn); | ||
235 | |||
236 | if (pfn >= max_low_pfn) | ||
237 | break; | ||
238 | } | ||
239 | } | ||
240 | #endif | ||
241 | |||
242 | /* | 210 | /* |
243 | * Find the highest page frame number we have available | 211 | * Find the highest page frame number we have available |
244 | */ | 212 | */ |
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c index 3b2e0b1bb49b..5e063e72b24a 100644 --- a/arch/x86/kernel/e820_64.c +++ b/arch/x86/kernel/e820_64.c | |||
@@ -17,7 +17,6 @@ | |||
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 | #include <linux/mm.h> |
20 | #include <linux/suspend.h> | ||
21 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
22 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
23 | 22 | ||
@@ -94,37 +93,6 @@ void __init e820_reserve_resources(void) | |||
94 | } | 93 | } |
95 | 94 | ||
96 | /* | 95 | /* |
97 | * Find the ranges of physical addresses that do not correspond to | ||
98 | * e820 RAM areas and mark the corresponding pages as nosave for software | ||
99 | * suspend and suspend to RAM. | ||
100 | * | ||
101 | * This function requires the e820 map to be sorted and without any | ||
102 | * overlapping entries and assumes the first e820 area to be RAM. | ||
103 | */ | ||
104 | void __init e820_mark_nosave_regions(void) | ||
105 | { | ||
106 | int i; | ||
107 | unsigned long paddr; | ||
108 | |||
109 | paddr = round_down(e820.map[0].addr + e820.map[0].size, PAGE_SIZE); | ||
110 | for (i = 1; i < e820.nr_map; i++) { | ||
111 | struct e820entry *ei = &e820.map[i]; | ||
112 | |||
113 | if (paddr < ei->addr) | ||
114 | register_nosave_region(PFN_DOWN(paddr), | ||
115 | PFN_UP(ei->addr)); | ||
116 | |||
117 | paddr = round_down(ei->addr + ei->size, PAGE_SIZE); | ||
118 | if (ei->type != E820_RAM) | ||
119 | register_nosave_region(PFN_UP(ei->addr), | ||
120 | PFN_DOWN(paddr)); | ||
121 | |||
122 | if (paddr >= (end_pfn << PAGE_SHIFT)) | ||
123 | break; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | /* | ||
128 | * Finds an active region in the address range from start_pfn to last_pfn and | 96 | * Finds an active region in the address range from start_pfn to last_pfn and |
129 | * returns its range in ei_startpfn and ei_endpfn for the e820 entry. | 97 | * returns its range in ei_startpfn and ei_endpfn for the e820 entry. |
130 | */ | 98 | */ |
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 3c451d143eba..e1173aecf69a 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -820,7 +820,7 @@ void __init setup_arch(char **cmdline_p) | |||
820 | #endif | 820 | #endif |
821 | 821 | ||
822 | e820_setup_gap(); | 822 | e820_setup_gap(); |
823 | e820_mark_nosave_regions(); | 823 | e820_mark_nosave_regions(max_low_pfn); |
824 | 824 | ||
825 | #ifdef CONFIG_VT | 825 | #ifdef CONFIG_VT |
826 | #if defined(CONFIG_VGA_CONSOLE) | 826 | #if defined(CONFIG_VGA_CONSOLE) |
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 6dff1286ad8a..975a5da46e49 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -516,7 +516,7 @@ void __init setup_arch(char **cmdline_p) | |||
516 | * We trust e820 completely. No explicit ROM probing in memory. | 516 | * We trust e820 completely. No explicit ROM probing in memory. |
517 | */ | 517 | */ |
518 | e820_reserve_resources(); | 518 | e820_reserve_resources(); |
519 | e820_mark_nosave_regions(); | 519 | e820_mark_nosave_regions(end_pfn); |
520 | 520 | ||
521 | /* request I/O space for devices used on all i[345]86 PCs */ | 521 | /* request I/O space for devices used on all i[345]86 PCs */ |
522 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | 522 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) |
diff --git a/include/asm-x86/e820.h b/include/asm-x86/e820.h index 5a58e2bb1d78..4266a2c5f2e8 100644 --- a/include/asm-x86/e820.h +++ b/include/asm-x86/e820.h | |||
@@ -70,6 +70,15 @@ extern u64 update_memory_range(u64 start, u64 size, unsigned old_type, | |||
70 | extern void update_e820(void); | 70 | extern void update_e820(void); |
71 | extern void e820_setup_gap(void); | 71 | extern void e820_setup_gap(void); |
72 | 72 | ||
73 | #if defined(CONFIG_X86_64) || \ | ||
74 | (defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION)) | ||
75 | extern void e820_mark_nosave_regions(unsigned long limit_pfn); | ||
76 | #else | ||
77 | static inline void e820_mark_nosave_regions(unsigned long limit_pfn) | ||
78 | { | ||
79 | } | ||
80 | #endif | ||
81 | |||
73 | extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); | 82 | extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align); |
74 | extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); | 83 | extern u64 find_e820_area_size(u64 start, u64 *sizep, u64 align); |
75 | extern void reserve_early(u64 start, u64 end, char *name); | 84 | extern void reserve_early(u64 start, u64 end, char *name); |
diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h index 9576b438fbd9..7ace82570a36 100644 --- a/include/asm-x86/e820_32.h +++ b/include/asm-x86/e820_32.h | |||
@@ -28,13 +28,5 @@ extern void init_iomem_resources(struct resource *code_resource, | |||
28 | struct resource *data_resource, | 28 | struct resource *data_resource, |
29 | struct resource *bss_resource); | 29 | struct resource *bss_resource); |
30 | 30 | ||
31 | #if defined(CONFIG_PM) && defined(CONFIG_HIBERNATION) | ||
32 | extern void e820_mark_nosave_regions(void); | ||
33 | #else | ||
34 | static inline void e820_mark_nosave_regions(void) | ||
35 | { | ||
36 | } | ||
37 | #endif | ||
38 | |||
39 | #endif/*!__ASSEMBLY__*/ | 31 | #endif/*!__ASSEMBLY__*/ |
40 | #endif/*__E820_HEADER*/ | 32 | #endif/*__E820_HEADER*/ |
diff --git a/include/asm-x86/e820_64.h b/include/asm-x86/e820_64.h index 37f176a02bc6..917963ccab69 100644 --- a/include/asm-x86/e820_64.h +++ b/include/asm-x86/e820_64.h | |||
@@ -18,7 +18,6 @@ extern void setup_memory_region(void); | |||
18 | extern void contig_e820_setup(void); | 18 | extern void contig_e820_setup(void); |
19 | extern unsigned long e820_end_of_ram(void); | 19 | extern unsigned long e820_end_of_ram(void); |
20 | extern void e820_reserve_resources(void); | 20 | extern void e820_reserve_resources(void); |
21 | extern void e820_mark_nosave_regions(void); | ||
22 | extern int e820_any_non_reserved(unsigned long start, unsigned long end); | 21 | extern int e820_any_non_reserved(unsigned long start, unsigned long end); |
23 | extern int is_memory_any_valid(unsigned long start, unsigned long end); | 22 | extern int is_memory_any_valid(unsigned long start, unsigned long end); |
24 | extern int e820_all_non_reserved(unsigned long start, unsigned long end); | 23 | extern int e820_all_non_reserved(unsigned long start, unsigned long end); |