aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/setup_64.c2
-rw-r--r--arch/x86/mm/init_64.c34
2 files changed, 24 insertions, 12 deletions
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 413b8fc31545..3d76dbd9f2c0 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -347,7 +347,7 @@ void __init setup_arch(char **cmdline_p)
347 347
348 check_efer(); 348 check_efer();
349 349
350 init_memory_mapping(0, (max_pfn_mapped << PAGE_SHIFT)); 350 max_pfn_mapped = init_memory_mapping(0, (max_pfn_mapped << PAGE_SHIFT));
351 if (efi_enabled) 351 if (efi_enabled)
352 efi_init(); 352 efi_init();
353 353
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index ef9e9cfb1fc2..1076097dcab2 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -313,7 +313,7 @@ __meminit void early_iounmap(void *addr, unsigned long size)
313 __flush_tlb_all(); 313 __flush_tlb_all();
314} 314}
315 315
316static void __meminit 316static unsigned long __meminit
317phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) 317phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
318{ 318{
319 int i = pmd_index(address); 319 int i = pmd_index(address);
@@ -335,21 +335,26 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
335 set_pte((pte_t *)pmd, 335 set_pte((pte_t *)pmd,
336 pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE)); 336 pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
337 } 337 }
338 return address;
338} 339}
339 340
340static void __meminit 341static unsigned long __meminit
341phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) 342phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end)
342{ 343{
343 pmd_t *pmd = pmd_offset(pud, 0); 344 pmd_t *pmd = pmd_offset(pud, 0);
345 unsigned long last_map_addr;
346
344 spin_lock(&init_mm.page_table_lock); 347 spin_lock(&init_mm.page_table_lock);
345 phys_pmd_init(pmd, address, end); 348 last_map_addr = phys_pmd_init(pmd, address, end);
346 spin_unlock(&init_mm.page_table_lock); 349 spin_unlock(&init_mm.page_table_lock);
347 __flush_tlb_all(); 350 __flush_tlb_all();
351 return last_map_addr;
348} 352}
349 353
350static void __meminit 354static unsigned long __meminit
351phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) 355phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
352{ 356{
357 unsigned long last_map_addr = end;
353 int i = pud_index(addr); 358 int i = pud_index(addr);
354 359
355 for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE) { 360 for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE) {
@@ -368,13 +373,14 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
368 373
369 if (pud_val(*pud)) { 374 if (pud_val(*pud)) {
370 if (!pud_large(*pud)) 375 if (!pud_large(*pud))
371 phys_pmd_update(pud, addr, end); 376 last_map_addr = phys_pmd_update(pud, addr, end);
372 continue; 377 continue;
373 } 378 }
374 379
375 if (direct_gbpages) { 380 if (direct_gbpages) {
376 set_pte((pte_t *)pud, 381 set_pte((pte_t *)pud,
377 pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_LARGE)); 382 pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
383 last_map_addr = (addr & PUD_MASK) + PUD_SIZE;
378 continue; 384 continue;
379 } 385 }
380 386
@@ -382,12 +388,14 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
382 388
383 spin_lock(&init_mm.page_table_lock); 389 spin_lock(&init_mm.page_table_lock);
384 set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); 390 set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
385 phys_pmd_init(pmd, addr, end); 391 last_map_addr = phys_pmd_init(pmd, addr, end);
386 spin_unlock(&init_mm.page_table_lock); 392 spin_unlock(&init_mm.page_table_lock);
387 393
388 unmap_low_page(pmd); 394 unmap_low_page(pmd);
389 } 395 }
390 __flush_tlb_all(); 396 __flush_tlb_all();
397
398 return last_map_addr >> PAGE_SHIFT;
391} 399}
392 400
393static void __init find_early_table_space(unsigned long end) 401static void __init find_early_table_space(unsigned long end)
@@ -542,9 +550,9 @@ static void __init early_memtest(unsigned long start, unsigned long end)
542 * This runs before bootmem is initialized and gets pages directly from 550 * This runs before bootmem is initialized and gets pages directly from
543 * the physical memory. To access them they are temporarily mapped. 551 * the physical memory. To access them they are temporarily mapped.
544 */ 552 */
545void __init_refok init_memory_mapping(unsigned long start, unsigned long end) 553unsigned long __init_refok init_memory_mapping(unsigned long start, unsigned long end)
546{ 554{
547 unsigned long next; 555 unsigned long next, last_map_addr = end;
548 unsigned long start_phys = start, end_phys = end; 556 unsigned long start_phys = start, end_phys = end;
549 557
550 printk(KERN_INFO "init_memory_mapping\n"); 558 printk(KERN_INFO "init_memory_mapping\n");
@@ -577,7 +585,7 @@ void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
577 next = start + PGDIR_SIZE; 585 next = start + PGDIR_SIZE;
578 if (next > end) 586 if (next > end)
579 next = end; 587 next = end;
580 phys_pud_init(pud, __pa(start), __pa(next)); 588 last_map_addr = phys_pud_init(pud, __pa(start), __pa(next));
581 if (!after_bootmem) 589 if (!after_bootmem)
582 set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); 590 set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
583 unmap_low_page(pud); 591 unmap_low_page(pud);
@@ -593,6 +601,8 @@ void __init_refok init_memory_mapping(unsigned long start, unsigned long end)
593 601
594 if (!after_bootmem) 602 if (!after_bootmem)
595 early_memtest(start_phys, end_phys); 603 early_memtest(start_phys, end_phys);
604
605 return last_map_addr;
596} 606}
597 607
598#ifndef CONFIG_NUMA 608#ifndef CONFIG_NUMA
@@ -632,11 +642,13 @@ int arch_add_memory(int nid, u64 start, u64 size)
632{ 642{
633 struct pglist_data *pgdat = NODE_DATA(nid); 643 struct pglist_data *pgdat = NODE_DATA(nid);
634 struct zone *zone = pgdat->node_zones + ZONE_NORMAL; 644 struct zone *zone = pgdat->node_zones + ZONE_NORMAL;
635 unsigned long start_pfn = start >> PAGE_SHIFT; 645 unsigned long last_mapped_pfn, start_pfn = start >> PAGE_SHIFT;
636 unsigned long nr_pages = size >> PAGE_SHIFT; 646 unsigned long nr_pages = size >> PAGE_SHIFT;
637 int ret; 647 int ret;
638 648
639 init_memory_mapping(start, start + size-1); 649 last_mapped_pfn = init_memory_mapping(start, start + size-1);
650 if (last_mapped_pfn > max_pfn_mapped)
651 max_pfn_mapped = last_mapped_pfn;
640 652
641 ret = __add_pages(zone, start_pfn, nr_pages); 653 ret = __add_pages(zone, start_pfn, nr_pages);
642 WARN_ON(1); 654 WARN_ON(1);