diff options
Diffstat (limited to 'arch/x86/mm/init_64.c')
-rw-r--r-- | arch/x86/mm/init_64.c | 23 |
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 | |||
407 | phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, | 407 | phys_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 | |||
482 | phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, | 484 | phys_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 | ||