diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/mm/init_64.c | 45 | ||||
-rw-r--r-- | arch/x86_64/Kconfig | 1 |
2 files changed, 46 insertions, 0 deletions
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 458893b376f8..7d4fc633a9c9 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -748,3 +748,48 @@ const char *arch_vma_name(struct vm_area_struct *vma) | |||
748 | return "[vsyscall]"; | 748 | return "[vsyscall]"; |
749 | return NULL; | 749 | return NULL; |
750 | } | 750 | } |
751 | |||
752 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | ||
753 | /* | ||
754 | * Initialise the sparsemem vmemmap using huge-pages at the PMD level. | ||
755 | */ | ||
756 | int __meminit vmemmap_populate(struct page *start_page, | ||
757 | unsigned long size, int node) | ||
758 | { | ||
759 | unsigned long addr = (unsigned long)start_page; | ||
760 | unsigned long end = (unsigned long)(start_page + size); | ||
761 | unsigned long next; | ||
762 | pgd_t *pgd; | ||
763 | pud_t *pud; | ||
764 | pmd_t *pmd; | ||
765 | |||
766 | for (; addr < end; addr = next) { | ||
767 | next = pmd_addr_end(addr, end); | ||
768 | |||
769 | pgd = vmemmap_pgd_populate(addr, node); | ||
770 | if (!pgd) | ||
771 | return -ENOMEM; | ||
772 | pud = vmemmap_pud_populate(pgd, addr, node); | ||
773 | if (!pud) | ||
774 | return -ENOMEM; | ||
775 | |||
776 | pmd = pmd_offset(pud, addr); | ||
777 | if (pmd_none(*pmd)) { | ||
778 | pte_t entry; | ||
779 | void *p = vmemmap_alloc_block(PMD_SIZE, node); | ||
780 | if (!p) | ||
781 | return -ENOMEM; | ||
782 | |||
783 | entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL); | ||
784 | mk_pte_huge(entry); | ||
785 | set_pmd(pmd, __pmd(pte_val(entry))); | ||
786 | |||
787 | printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n", | ||
788 | addr, addr + PMD_SIZE - 1, p, node); | ||
789 | } else | ||
790 | vmemmap_verify((pte_t *)pmd, node, addr, next); | ||
791 | } | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | #endif | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index cf013cb85ea4..8c83dbe4c4d0 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -409,6 +409,7 @@ config ARCH_DISCONTIGMEM_DEFAULT | |||
409 | config ARCH_SPARSEMEM_ENABLE | 409 | config ARCH_SPARSEMEM_ENABLE |
410 | def_bool y | 410 | def_bool y |
411 | depends on (NUMA || EXPERIMENTAL) | 411 | depends on (NUMA || EXPERIMENTAL) |
412 | select SPARSEMEM_VMEMMAP_ENABLE | ||
412 | 413 | ||
413 | config ARCH_MEMORY_PROBE | 414 | config ARCH_MEMORY_PROBE |
414 | def_bool y | 415 | def_bool y |