aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/init_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/mm/init_64.c')
-rw-r--r--arch/x86/mm/init_64.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index fc18be0f6f29..2b6b4a3c8beb 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -407,12 +407,12 @@ static unsigned long __meminit
407phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, 407phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
408 unsigned long page_size_mask, pgprot_t prot) 408 unsigned long page_size_mask, pgprot_t prot)
409{ 409{
410 unsigned long pages = 0; 410 unsigned long pages = 0, next;
411 unsigned long last_map_addr = end; 411 unsigned long last_map_addr = end;
412 412
413 int i = pmd_index(address); 413 int i = pmd_index(address);
414 414
415 for (; i < PTRS_PER_PMD; i++, address += PMD_SIZE) { 415 for (; i < PTRS_PER_PMD; i++, address = next) {
416 unsigned long pte_phys; 416 unsigned long pte_phys;
417 pmd_t *pmd = pmd_page + pmd_index(address); 417 pmd_t *pmd = pmd_page + pmd_index(address);
418 pte_t *pte; 418 pte_t *pte;
@@ -426,6 +426,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
426 break; 426 break;
427 } 427 }
428 428
429 next = (address & PMD_MASK) + PMD_SIZE;
430
429 if (pmd_val(*pmd)) { 431 if (pmd_val(*pmd)) {
430 if (!pmd_large(*pmd)) { 432 if (!pmd_large(*pmd)) {
431 spin_lock(&init_mm.page_table_lock); 433 spin_lock(&init_mm.page_table_lock);
@@ -449,7 +451,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
449 * attributes. 451 * attributes.
450 */ 452 */
451 if (page_size_mask & (1 << PG_LEVEL_2M)) { 453 if (page_size_mask & (1 << PG_LEVEL_2M)) {
452 pages++; 454 last_map_addr = next;
453 continue; 455 continue;
454 } 456 }
455 new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd)); 457 new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd));
@@ -462,7 +464,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
462 pfn_pte(address >> PAGE_SHIFT, 464 pfn_pte(address >> PAGE_SHIFT,
463 __pgprot(pgprot_val(prot) | _PAGE_PSE))); 465 __pgprot(pgprot_val(prot) | _PAGE_PSE)));
464 spin_unlock(&init_mm.page_table_lock); 466 spin_unlock(&init_mm.page_table_lock);
465 last_map_addr = (address & PMD_MASK) + PMD_SIZE; 467 last_map_addr = next;
466 continue; 468 continue;
467 } 469 }
468 470
@@ -482,11 +484,11 @@ static unsigned long __meminit
482phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, 484phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
483 unsigned long page_size_mask) 485 unsigned long page_size_mask)
484{ 486{
485 unsigned long pages = 0; 487 unsigned long pages = 0, next;
486 unsigned long last_map_addr = end; 488 unsigned long last_map_addr = end;
487 int i = pud_index(addr); 489 int i = pud_index(addr);
488 490
489 for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE) { 491 for (; i < PTRS_PER_PUD; i++, addr = next) {
490 unsigned long pmd_phys; 492 unsigned long pmd_phys;
491 pud_t *pud = pud_page + pud_index(addr); 493 pud_t *pud = pud_page + pud_index(addr);
492 pmd_t *pmd; 494 pmd_t *pmd;
@@ -495,8 +497,9 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
495 if (addr >= end) 497 if (addr >= end)
496 break; 498 break;
497 499
498 if (!after_bootmem && 500 next = (addr & PUD_MASK) + PUD_SIZE;
499 !e820_any_mapped(addr, addr+PUD_SIZE, 0)) { 501
502 if (!after_bootmem && !e820_any_mapped(addr, next, 0)) {
500 set_pud(pud, __pud(0)); 503 set_pud(pud, __pud(0));
501 continue; 504 continue;
502 } 505 }
@@ -523,7 +526,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
523 * attributes. 526 * attributes.
524 */ 527 */
525 if (page_size_mask & (1 << PG_LEVEL_1G)) { 528 if (page_size_mask & (1 << PG_LEVEL_1G)) {
526 pages++; 529 last_map_addr = next;
527 continue; 530 continue;
528 } 531 }
529 prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud)); 532 prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud));
@@ -535,7 +538,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
535 set_pte((pte_t *)pud, 538 set_pte((pte_t *)pud,
536 pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_LARGE)); 539 pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
537 spin_unlock(&init_mm.page_table_lock); 540 spin_unlock(&init_mm.page_table_lock);
538 last_map_addr = (addr & PUD_MASK) + PUD_SIZE; 541 last_map_addr = next;
539 continue; 542 continue;
540 } 543 }
541 544