aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/init.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/x86/mm/init.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/x86/mm/init.c')
-rw-r--r--arch/x86/mm/init.c85
1 files changed, 39 insertions, 46 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index b278535b14aa..30326443ab81 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -2,6 +2,7 @@
2#include <linux/initrd.h> 2#include <linux/initrd.h>
3#include <linux/ioport.h> 3#include <linux/ioport.h>
4#include <linux/swap.h> 4#include <linux/swap.h>
5#include <linux/memblock.h>
5 6
6#include <asm/cacheflush.h> 7#include <asm/cacheflush.h>
7#include <asm/e820.h> 8#include <asm/e820.h>
@@ -15,11 +16,9 @@
15#include <asm/tlb.h> 16#include <asm/tlb.h>
16#include <asm/proto.h> 17#include <asm/proto.h>
17 18
18DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 19unsigned long __initdata pgt_buf_start;
19 20unsigned long __meminitdata pgt_buf_end;
20unsigned long __initdata e820_table_start; 21unsigned long __meminitdata pgt_buf_top;
21unsigned long __meminitdata e820_table_end;
22unsigned long __meminitdata e820_table_top;
23 22
24int after_bootmem; 23int after_bootmem;
25 24
@@ -32,7 +31,8 @@ int direct_gbpages
32static void __init find_early_table_space(unsigned long end, int use_pse, 31static void __init find_early_table_space(unsigned long end, int use_pse,
33 int use_gbpages) 32 int use_gbpages)
34{ 33{
35 unsigned long puds, pmds, ptes, tables, start; 34 unsigned long puds, pmds, ptes, tables, start = 0, good_end = end;
35 phys_addr_t base;
36 36
37 puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; 37 puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
38 tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); 38 tables = roundup(puds * sizeof(pud_t), PAGE_SIZE);
@@ -63,29 +63,25 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
63#ifdef CONFIG_X86_32 63#ifdef CONFIG_X86_32
64 /* for fixmap */ 64 /* for fixmap */
65 tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE); 65 tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE);
66#endif
67 66
68 /* 67 good_end = max_pfn_mapped << PAGE_SHIFT;
69 * RED-PEN putting page tables only on node 0 could
70 * cause a hotspot and fill up ZONE_DMA. The page tables
71 * need roughly 0.5KB per GB.
72 */
73#ifdef CONFIG_X86_32
74 start = 0x7000;
75#else
76 start = 0x8000;
77#endif 68#endif
78 e820_table_start = find_e820_area(start, max_pfn_mapped<<PAGE_SHIFT, 69
79 tables, PAGE_SIZE); 70 base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE);
80 if (e820_table_start == -1UL) 71 if (base == MEMBLOCK_ERROR)
81 panic("Cannot find space for the kernel page tables"); 72 panic("Cannot find space for the kernel page tables");
82 73
83 e820_table_start >>= PAGE_SHIFT; 74 pgt_buf_start = base >> PAGE_SHIFT;
84 e820_table_end = e820_table_start; 75 pgt_buf_end = pgt_buf_start;
85 e820_table_top = e820_table_start + (tables >> PAGE_SHIFT); 76 pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT);
86 77
87 printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n", 78 printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n",
88 end, e820_table_start << PAGE_SHIFT, e820_table_top << PAGE_SHIFT); 79 end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT);
80}
81
82void __init native_pagetable_reserve(u64 start, u64 end)
83{
84 memblock_x86_reserve_range(start, end, "PGTABLE");
89} 85}
90 86
91struct map_range { 87struct map_range {
@@ -277,30 +273,26 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
277 load_cr3(swapper_pg_dir); 273 load_cr3(swapper_pg_dir);
278#endif 274#endif
279 275
280#ifdef CONFIG_X86_64
281 if (!after_bootmem && !start) {
282 pud_t *pud;
283 pmd_t *pmd;
284
285 mmu_cr4_features = read_cr4();
286
287 /*
288 * _brk_end cannot change anymore, but it and _end may be
289 * located on different 2M pages. cleanup_highmap(), however,
290 * can only consider _end when it runs, so destroy any
291 * mappings beyond _brk_end here.
292 */
293 pud = pud_offset(pgd_offset_k(_brk_end), _brk_end);
294 pmd = pmd_offset(pud, _brk_end - 1);
295 while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1))
296 pmd_clear(pmd);
297 }
298#endif
299 __flush_tlb_all(); 276 __flush_tlb_all();
300 277
301 if (!after_bootmem && e820_table_end > e820_table_start) 278 /*
302 reserve_early(e820_table_start << PAGE_SHIFT, 279 * Reserve the kernel pagetable pages we used (pgt_buf_start -
303 e820_table_end << PAGE_SHIFT, "PGTABLE"); 280 * pgt_buf_end) and free the other ones (pgt_buf_end - pgt_buf_top)
281 * so that they can be reused for other purposes.
282 *
283 * On native it just means calling memblock_x86_reserve_range, on Xen it
284 * also means marking RW the pagetable pages that we allocated before
285 * but that haven't been used.
286 *
287 * In fact on xen we mark RO the whole range pgt_buf_start -
288 * pgt_buf_top, because we have to make sure that when
289 * init_memory_mapping reaches the pagetable pages area, it maps
290 * RO all the pagetable pages, including the ones that are beyond
291 * pgt_buf_end at that time.
292 */
293 if (!after_bootmem && pgt_buf_end > pgt_buf_start)
294 x86_init.mapping.pagetable_reserve(PFN_PHYS(pgt_buf_start),
295 PFN_PHYS(pgt_buf_end));
304 296
305 if (!after_bootmem) 297 if (!after_bootmem)
306 early_memtest(start, end); 298 early_memtest(start, end);
@@ -362,8 +354,9 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
362 /* 354 /*
363 * We just marked the kernel text read only above, now that 355 * We just marked the kernel text read only above, now that
364 * we are going to free part of that, we need to make that 356 * we are going to free part of that, we need to make that
365 * writeable first. 357 * writeable and non-executable first.
366 */ 358 */
359 set_memory_nx(begin, (end - begin) >> PAGE_SHIFT);
367 set_memory_rw(begin, (end - begin) >> PAGE_SHIFT); 360 set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
368 361
369 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); 362 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);