aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/e820_32.c68
-rw-r--r--arch/x86/kernel/numaq_32.c3
-rw-r--r--arch/x86/kernel/setup_32.c24
-rw-r--r--arch/x86/kernel/srat_32.c4
-rw-r--r--arch/x86/mm/discontig_32.c19
5 files changed, 33 insertions, 85 deletions
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c
index 0c025d04fc2e..e8a3b968c9fa 100644
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -207,69 +207,6 @@ void __init init_iomem_resources(struct resource *code_resource,
207 } 207 }
208} 208}
209 209
210/*
211 * Find the highest page frame number we have available
212 */
213void __init find_max_pfn(void)
214{
215 int i;
216
217 max_pfn = 0;
218
219 for (i = 0; i < e820.nr_map; i++) {
220 unsigned long start, end;
221 /* RAM? */
222 if (e820.map[i].type != E820_RAM)
223 continue;
224 start = PFN_UP(e820.map[i].addr);
225 end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
226 if (start >= end)
227 continue;
228 if (end > max_pfn)
229 max_pfn = end;
230 }
231}
232
233/*
234 * Register fully available low RAM pages with the bootmem allocator.
235 */
236void __init register_bootmem_low_pages(unsigned long max_low_pfn)
237{
238 int i;
239
240 for (i = 0; i < e820.nr_map; i++) {
241 unsigned long curr_pfn, last_pfn, size;
242 /*
243 * Reserve usable low memory
244 */
245 if (e820.map[i].type != E820_RAM)
246 continue;
247 /*
248 * We are rounding up the start address of usable memory:
249 */
250 curr_pfn = PFN_UP(e820.map[i].addr);
251 if (curr_pfn >= max_low_pfn)
252 continue;
253 /*
254 * ... and at the end of the usable range downwards:
255 */
256 last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
257
258 if (last_pfn > max_low_pfn)
259 last_pfn = max_low_pfn;
260
261 /*
262 * .. finally, did all the rounding and playing
263 * around just make the area go away?
264 */
265 if (last_pfn <= curr_pfn)
266 continue;
267
268 size = last_pfn - curr_pfn;
269 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
270 }
271}
272
273void __init limit_regions(unsigned long long size) 210void __init limit_regions(unsigned long long size)
274{ 211{
275 unsigned long long current_addr; 212 unsigned long long current_addr;
@@ -360,8 +297,9 @@ static int __init parse_memmap(char *arg)
360 * size before original memory map is 297 * size before original memory map is
361 * reset. 298 * reset.
362 */ 299 */
363 find_max_pfn(); 300 e820_register_active_regions(0, 0, -1UL);
364 saved_max_pfn = max_pfn; 301 saved_max_pfn = e820_end_of_ram();
302 remove_all_active_ranges();
365#endif 303#endif
366 e820.nr_map = 0; 304 e820.nr_map = 0;
367 user_defined_memmap = 1; 305 user_defined_memmap = 1;
diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c
index 922be66668b8..27b908254fb0 100644
--- a/arch/x86/kernel/numaq_32.c
+++ b/arch/x86/kernel/numaq_32.c
@@ -32,6 +32,7 @@
32#include <asm/topology.h> 32#include <asm/topology.h>
33#include <asm/processor.h> 33#include <asm/processor.h>
34#include <asm/mpspec.h> 34#include <asm/mpspec.h>
35#include <asm/e820.h>
35 36
36#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) 37#define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))
37 38
@@ -61,6 +62,8 @@ static void __init smp_dump_qct(void)
61 node_end_pfn[node] = MB_TO_PAGES( 62 node_end_pfn[node] = MB_TO_PAGES(
62 eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); 63 eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
63 64
65 e820_register_active_regions(node, node_start_pfn[node],
66 node_end_pfn[node]);
64 memory_present(node, 67 memory_present(node,
65 node_start_pfn[node], node_end_pfn[node]); 68 node_start_pfn[node], node_end_pfn[node]);
66 node_remap_size[node] = node_memmap_size_bytes(node, 69 node_remap_size[node] = node_memmap_size_bytes(node,
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index ccf3595202fa..0ec6480aaa27 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -405,11 +405,12 @@ static void __init zone_sizes_init(void)
405 max_zone_pfns[ZONE_DMA] = 405 max_zone_pfns[ZONE_DMA] =
406 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 406 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
407 max_zone_pfns[ZONE_NORMAL] = max_low_pfn; 407 max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
408 remove_all_active_ranges();
408#ifdef CONFIG_HIGHMEM 409#ifdef CONFIG_HIGHMEM
409 max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; 410 max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
410 add_active_range(0, 0, highend_pfn); 411 e820_register_active_regions(0, 0, highend_pfn);
411#else 412#else
412 add_active_range(0, 0, max_low_pfn); 413 e820_register_active_regions(0, 0, max_low_pfn);
413#endif 414#endif
414 415
415 free_area_init_nodes(max_zone_pfns); 416 free_area_init_nodes(max_zone_pfns);
@@ -582,6 +583,7 @@ static void __init relocate_initrd(void)
582 583
583void __init setup_bootmem_allocator(void) 584void __init setup_bootmem_allocator(void)
584{ 585{
586 int i;
585 unsigned long bootmap_size, bootmap; 587 unsigned long bootmap_size, bootmap;
586 /* 588 /*
587 * Initialize the boot-time allocator (with low memory only): 589 * Initialize the boot-time allocator (with low memory only):
@@ -603,7 +605,8 @@ void __init setup_bootmem_allocator(void)
603 min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT); 605 min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT);
604 printk(KERN_INFO " bootmap %08lx - %08lx\n", 606 printk(KERN_INFO " bootmap %08lx - %08lx\n",
605 bootmap, bootmap + bootmap_size); 607 bootmap, bootmap + bootmap_size);
606 register_bootmem_low_pages(max_low_pfn); 608 for_each_online_node(i)
609 free_bootmem_with_active_regions(i, max_low_pfn);
607 early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); 610 early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT);
608 611
609#ifdef CONFIG_ACPI_SLEEP 612#ifdef CONFIG_ACPI_SLEEP
@@ -733,11 +736,20 @@ void __init setup_arch(char **cmdline_p)
733 if (efi_enabled) 736 if (efi_enabled)
734 efi_init(); 737 efi_init();
735 738
739 e820_register_active_regions(0, 0, -1UL);
740 /*
741 * partially used pages are not usable - thus
742 * we are rounding upwards:
743 */
744 max_pfn = e820_end_of_ram();
745
736 /* update e820 for memory not covered by WB MTRRs */ 746 /* update e820 for memory not covered by WB MTRRs */
737 find_max_pfn();
738 mtrr_bp_init(); 747 mtrr_bp_init();
739 if (mtrr_trim_uncached_memory(max_pfn)) 748 if (mtrr_trim_uncached_memory(max_pfn)) {
740 find_max_pfn(); 749 remove_all_active_ranges();
750 e820_register_active_regions(0, 0, -1UL);
751 max_pfn = e820_end_of_ram();
752 }
741 753
742 max_low_pfn = setup_memory(); 754 max_low_pfn = setup_memory();
743 755
diff --git a/arch/x86/kernel/srat_32.c b/arch/x86/kernel/srat_32.c
index 88971ee166d4..32d8b1142938 100644
--- a/arch/x86/kernel/srat_32.c
+++ b/arch/x86/kernel/srat_32.c
@@ -31,6 +31,7 @@
31#include <asm/srat.h> 31#include <asm/srat.h>
32#include <asm/topology.h> 32#include <asm/topology.h>
33#include <asm/smp.h> 33#include <asm/smp.h>
34#include <asm/e820.h>
34 35
35/* 36/*
36 * proximity macros and definitions 37 * proximity macros and definitions
@@ -244,7 +245,8 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
244 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", 245 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
245 j, chunk->nid, chunk->start_pfn, chunk->end_pfn); 246 j, chunk->nid, chunk->start_pfn, chunk->end_pfn);
246 node_read_chunk(chunk->nid, chunk); 247 node_read_chunk(chunk->nid, chunk);
247 add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn); 248 e820_register_active_regions(chunk->nid, chunk->start_pfn,
249 min(chunk->end_pfn, max_pfn));
248 } 250 }
249 251
250 for_each_online_node(nid) { 252 for_each_online_node(nid) {
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c
index 7ced26ab9aec..a89ccf3d4c14 100644
--- a/arch/x86/mm/discontig_32.c
+++ b/arch/x86/mm/discontig_32.c
@@ -120,10 +120,9 @@ int __init get_memcfg_numa_flat(void)
120{ 120{
121 printk("NUMA - single node, flat memory mode\n"); 121 printk("NUMA - single node, flat memory mode\n");
122 122
123 /* Run the memory configuration and find the top of memory. */
124 find_max_pfn();
125 node_start_pfn[0] = 0; 123 node_start_pfn[0] = 0;
126 node_end_pfn[0] = max_pfn; 124 node_end_pfn[0] = max_pfn;
125 e820_register_active_regions(0, 0, max_pfn);
127 memory_present(0, 0, max_pfn); 126 memory_present(0, 0, max_pfn);
128 node_remap_size[0] = node_memmap_size_bytes(0, 0, max_pfn); 127 node_remap_size[0] = node_memmap_size_bytes(0, 0, max_pfn);
129 128
@@ -337,6 +336,11 @@ unsigned long __init setup_memory(void)
337 * this space and use it to adjust the boundary between ZONE_NORMAL 336 * this space and use it to adjust the boundary between ZONE_NORMAL
338 * and ZONE_HIGHMEM. 337 * and ZONE_HIGHMEM.
339 */ 338 */
339
340 /* call find_max_low_pfn at first, it could update max_pfn */
341 system_max_low_pfn = max_low_pfn = find_max_low_pfn();
342
343 remove_all_active_ranges();
340 get_memcfg_numa(); 344 get_memcfg_numa();
341 345
342 kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE); 346 kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE);
@@ -344,7 +348,6 @@ unsigned long __init setup_memory(void)
344 /* partially used pages are not usable - thus round upwards */ 348 /* partially used pages are not usable - thus round upwards */
345 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); 349 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end);
346 350
347 system_max_low_pfn = max_low_pfn = find_max_low_pfn();
348 kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE); 351 kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE);
349 do { 352 do {
350 kva_start_pfn = find_e820_area(kva_target_pfn<<PAGE_SHIFT, 353 kva_start_pfn = find_e820_area(kva_target_pfn<<PAGE_SHIFT,
@@ -402,7 +405,6 @@ unsigned long __init setup_memory(void)
402 405
403void __init zone_sizes_init(void) 406void __init zone_sizes_init(void)
404{ 407{
405 int nid;
406 unsigned long max_zone_pfns[MAX_NR_ZONES]; 408 unsigned long max_zone_pfns[MAX_NR_ZONES];
407 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 409 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
408 max_zone_pfns[ZONE_DMA] = 410 max_zone_pfns[ZONE_DMA] =
@@ -412,15 +414,6 @@ void __init zone_sizes_init(void)
412 max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; 414 max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
413#endif 415#endif
414 416
415 /* If SRAT has not registered memory, register it now */
416 if (find_max_pfn_with_active_regions() == 0) {
417 for_each_online_node(nid) {
418 if (node_has_online_mem(nid))
419 add_active_range(nid, node_start_pfn[nid],
420 node_end_pfn[nid]);
421 }
422 }
423
424 free_area_init_nodes(max_zone_pfns); 417 free_area_init_nodes(max_zone_pfns);
425 return; 418 return;
426} 419}