aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/mm/init_64.c45
-rw-r--r--arch/x86_64/Kconfig1
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 */
756int __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
409config ARCH_SPARSEMEM_ENABLE 409config 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
413config ARCH_MEMORY_PROBE 414config ARCH_MEMORY_PROBE
414 def_bool y 415 def_bool y