diff options
Diffstat (limited to 'arch/x86/mm/init.c')
| -rw-r--r-- | arch/x86/mm/init.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 286d289b039b..37b8b0fe8320 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
| @@ -81,6 +81,11 @@ static void __init find_early_table_space(unsigned long end, int use_pse, | |||
| 81 | end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT); | 81 | end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void __init native_pagetable_reserve(u64 start, u64 end) | ||
| 85 | { | ||
| 86 | memblock_x86_reserve_range(start, end, "PGTABLE"); | ||
| 87 | } | ||
| 88 | |||
| 84 | struct map_range { | 89 | struct map_range { |
| 85 | unsigned long start; | 90 | unsigned long start; |
| 86 | unsigned long end; | 91 | unsigned long end; |
| @@ -272,9 +277,24 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, | |||
| 272 | 277 | ||
| 273 | __flush_tlb_all(); | 278 | __flush_tlb_all(); |
| 274 | 279 | ||
| 280 | /* | ||
| 281 | * Reserve the kernel pagetable pages we used (pgt_buf_start - | ||
| 282 | * pgt_buf_end) and free the other ones (pgt_buf_end - pgt_buf_top) | ||
| 283 | * so that they can be reused for other purposes. | ||
| 284 | * | ||
| 285 | * On native it just means calling memblock_x86_reserve_range, on Xen it | ||
| 286 | * also means marking RW the pagetable pages that we allocated before | ||
| 287 | * but that haven't been used. | ||
| 288 | * | ||
| 289 | * In fact on xen we mark RO the whole range pgt_buf_start - | ||
| 290 | * pgt_buf_top, because we have to make sure that when | ||
| 291 | * init_memory_mapping reaches the pagetable pages area, it maps | ||
| 292 | * RO all the pagetable pages, including the ones that are beyond | ||
| 293 | * pgt_buf_end at that time. | ||
| 294 | */ | ||
| 275 | if (!after_bootmem && pgt_buf_end > pgt_buf_start) | 295 | if (!after_bootmem && pgt_buf_end > pgt_buf_start) |
| 276 | memblock_x86_reserve_range(pgt_buf_start << PAGE_SHIFT, | 296 | x86_init.mapping.pagetable_reserve(PFN_PHYS(pgt_buf_start), |
| 277 | pgt_buf_end << PAGE_SHIFT, "PGTABLE"); | 297 | PFN_PHYS(pgt_buf_end)); |
| 278 | 298 | ||
| 279 | if (!after_bootmem) | 299 | if (!after_bootmem) |
| 280 | early_memtest(start, end); | 300 | early_memtest(start, end); |
