diff options
-rw-r--r-- | arch/x86/include/asm/page_types.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/x86/mm/amdtopology_64.c | 8 | ||||
-rw-r--r-- | arch/x86/mm/init.c | 8 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 54 | ||||
-rw-r--r-- | arch/x86/mm/numa_64.c | 6 | ||||
-rw-r--r-- | arch/x86/mm/srat_64.c | 2 |
7 files changed, 68 insertions, 20 deletions
diff --git a/arch/x86/include/asm/page_types.h b/arch/x86/include/asm/page_types.h index 93626e69967..731d211a1b2 100644 --- a/arch/x86/include/asm/page_types.h +++ b/arch/x86/include/asm/page_types.h | |||
@@ -54,6 +54,8 @@ static inline phys_addr_t get_max_mapped(void) | |||
54 | extern unsigned long init_memory_mapping(unsigned long start, | 54 | extern unsigned long init_memory_mapping(unsigned long start, |
55 | unsigned long end); | 55 | unsigned long end); |
56 | 56 | ||
57 | void init_memory_mapping_high(void); | ||
58 | |||
57 | extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn, | 59 | extern void initmem_init(unsigned long start_pfn, unsigned long end_pfn, |
58 | int acpi, int k8); | 60 | int acpi, int k8); |
59 | extern void free_initmem(void); | 61 | extern void free_initmem(void); |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 3def8c9a5dc..fc0fe743f3a 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -931,14 +931,6 @@ void __init setup_arch(char **cmdline_p) | |||
931 | max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); | 931 | max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); |
932 | max_pfn_mapped = max_low_pfn_mapped; | 932 | max_pfn_mapped = max_low_pfn_mapped; |
933 | 933 | ||
934 | #ifdef CONFIG_X86_64 | ||
935 | if (max_pfn > max_low_pfn) { | ||
936 | max_pfn_mapped = init_memory_mapping(1UL<<32, | ||
937 | max_pfn<<PAGE_SHIFT); | ||
938 | /* can we preseve max_low_pfn ?*/ | ||
939 | max_low_pfn = max_pfn; | ||
940 | } | ||
941 | #endif | ||
942 | memblock.current_limit = get_max_mapped(); | 934 | memblock.current_limit = get_max_mapped(); |
943 | 935 | ||
944 | /* | 936 | /* |
diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c index 51fae9cfdec..ae6ad691a14 100644 --- a/arch/x86/mm/amdtopology_64.c +++ b/arch/x86/mm/amdtopology_64.c | |||
@@ -221,12 +221,14 @@ int __init amd_scan_nodes(void) | |||
221 | apicid_base = boot_cpu_physical_apicid; | 221 | apicid_base = boot_cpu_physical_apicid; |
222 | } | 222 | } |
223 | 223 | ||
224 | for_each_node_mask(i, node_possible_map) { | 224 | for_each_node_mask(i, node_possible_map) |
225 | int j; | ||
226 | |||
227 | memblock_x86_register_active_regions(i, | 225 | memblock_x86_register_active_regions(i, |
228 | nodes[i].start >> PAGE_SHIFT, | 226 | nodes[i].start >> PAGE_SHIFT, |
229 | nodes[i].end >> PAGE_SHIFT); | 227 | nodes[i].end >> PAGE_SHIFT); |
228 | init_memory_mapping_high(); | ||
229 | for_each_node_mask(i, node_possible_map) { | ||
230 | int j; | ||
231 | |||
230 | for (j = apicid_base; j < cores + apicid_base; j++) | 232 | for (j = apicid_base; j < cores + apicid_base; j++) |
231 | apicid_to_node[(i << bits) + j] = i; | 233 | apicid_to_node[(i << bits) + j] = i; |
232 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 234 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 5863950ebe0..fa6fe756d91 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
@@ -65,16 +65,10 @@ static void __init find_early_table_space(unsigned long end, int use_pse, | |||
65 | #ifdef CONFIG_X86_32 | 65 | #ifdef CONFIG_X86_32 |
66 | /* for fixmap */ | 66 | /* for fixmap */ |
67 | tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE); | 67 | tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE); |
68 | #endif | ||
69 | 68 | ||
70 | /* | ||
71 | * RED-PEN putting page tables only on node 0 could | ||
72 | * cause a hotspot and fill up ZONE_DMA. The page tables | ||
73 | * need roughly 0.5KB per GB. | ||
74 | */ | ||
75 | #ifdef CONFIG_X86_32 | ||
76 | good_end = max_pfn_mapped << PAGE_SHIFT; | 69 | good_end = max_pfn_mapped << PAGE_SHIFT; |
77 | #endif | 70 | #endif |
71 | |||
78 | base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE); | 72 | base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE); |
79 | if (base == MEMBLOCK_ERROR) | 73 | if (base == MEMBLOCK_ERROR) |
80 | panic("Cannot find space for the kernel page tables"); | 74 | panic("Cannot find space for the kernel page tables"); |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 024847dc81a..194f2732ab7 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -607,9 +607,63 @@ void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn, | |||
607 | int acpi, int k8) | 607 | int acpi, int k8) |
608 | { | 608 | { |
609 | memblock_x86_register_active_regions(0, start_pfn, end_pfn); | 609 | memblock_x86_register_active_regions(0, start_pfn, end_pfn); |
610 | init_memory_mapping_high(); | ||
610 | } | 611 | } |
611 | #endif | 612 | #endif |
612 | 613 | ||
614 | struct mapping_work_data { | ||
615 | unsigned long start; | ||
616 | unsigned long end; | ||
617 | unsigned long pfn_mapped; | ||
618 | }; | ||
619 | |||
620 | static int __init_refok | ||
621 | mapping_work_fn(unsigned long start_pfn, unsigned long end_pfn, void *datax) | ||
622 | { | ||
623 | struct mapping_work_data *data = datax; | ||
624 | unsigned long pfn_mapped; | ||
625 | unsigned long final_start, final_end; | ||
626 | |||
627 | final_start = max_t(unsigned long, start_pfn<<PAGE_SHIFT, data->start); | ||
628 | final_end = min_t(unsigned long, end_pfn<<PAGE_SHIFT, data->end); | ||
629 | |||
630 | if (final_end <= final_start) | ||
631 | return 0; | ||
632 | |||
633 | pfn_mapped = init_memory_mapping(final_start, final_end); | ||
634 | |||
635 | if (pfn_mapped > data->pfn_mapped) | ||
636 | data->pfn_mapped = pfn_mapped; | ||
637 | |||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | static unsigned long __init_refok | ||
642 | init_memory_mapping_active_regions(unsigned long start, unsigned long end) | ||
643 | { | ||
644 | struct mapping_work_data data; | ||
645 | |||
646 | data.start = start; | ||
647 | data.end = end; | ||
648 | data.pfn_mapped = 0; | ||
649 | |||
650 | work_with_active_regions(MAX_NUMNODES, mapping_work_fn, &data); | ||
651 | |||
652 | return data.pfn_mapped; | ||
653 | } | ||
654 | |||
655 | void __init_refok init_memory_mapping_high(void) | ||
656 | { | ||
657 | if (max_pfn > max_low_pfn) { | ||
658 | max_pfn_mapped = init_memory_mapping_active_regions(1UL<<32, | ||
659 | max_pfn<<PAGE_SHIFT); | ||
660 | /* can we preserve max_low_pfn ? */ | ||
661 | max_low_pfn = max_pfn; | ||
662 | |||
663 | memblock.current_limit = get_max_mapped(); | ||
664 | } | ||
665 | } | ||
666 | |||
613 | void __init paging_init(void) | 667 | void __init paging_init(void) |
614 | { | 668 | { |
615 | unsigned long max_zone_pfns[MAX_NR_ZONES]; | 669 | unsigned long max_zone_pfns[MAX_NR_ZONES]; |
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 02d36ff85eb..7cc26ae0a15 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -590,11 +590,12 @@ static int __init numa_emulation(unsigned long start_pfn, | |||
590 | * the e820 memory map. | 590 | * the e820 memory map. |
591 | */ | 591 | */ |
592 | remove_all_active_ranges(); | 592 | remove_all_active_ranges(); |
593 | for_each_node_mask(i, node_possible_map) { | 593 | for_each_node_mask(i, node_possible_map) |
594 | memblock_x86_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, | 594 | memblock_x86_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, |
595 | nodes[i].end >> PAGE_SHIFT); | 595 | nodes[i].end >> PAGE_SHIFT); |
596 | init_memory_mapping_high(); | ||
597 | for_each_node_mask(i, node_possible_map) | ||
596 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 598 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); |
597 | } | ||
598 | acpi_fake_nodes(nodes, num_nodes); | 599 | acpi_fake_nodes(nodes, num_nodes); |
599 | numa_init_array(); | 600 | numa_init_array(); |
600 | return 0; | 601 | return 0; |
@@ -645,6 +646,7 @@ void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn, | |||
645 | for (i = 0; i < nr_cpu_ids; i++) | 646 | for (i = 0; i < nr_cpu_ids; i++) |
646 | numa_set_node(i, 0); | 647 | numa_set_node(i, 0); |
647 | memblock_x86_register_active_regions(0, start_pfn, last_pfn); | 648 | memblock_x86_register_active_regions(0, start_pfn, last_pfn); |
649 | init_memory_mapping_high(); | ||
648 | setup_node_bootmem(0, start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT); | 650 | setup_node_bootmem(0, start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT); |
649 | } | 651 | } |
650 | 652 | ||
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index a35cb9d8b06..0b961c8bffb 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -433,6 +433,8 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
433 | return -1; | 433 | return -1; |
434 | } | 434 | } |
435 | 435 | ||
436 | init_memory_mapping_high(); | ||
437 | |||
436 | /* Account for nodes with cpus and no memory */ | 438 | /* Account for nodes with cpus and no memory */ |
437 | nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed); | 439 | nodes_or(node_possible_map, nodes_parsed, cpu_nodes_parsed); |
438 | 440 | ||