diff options
Diffstat (limited to 'mm/sparse-vmemmap.c')
| -rw-r--r-- | mm/sparse-vmemmap.c | 22 | 
1 files changed, 19 insertions, 3 deletions
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 574c67b663fe..a56c3989f773 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -196,9 +196,9 @@ pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)  	return pmd;  } -pud_t * __meminit vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node) +pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node)  { -	pud_t *pud = pud_offset(pgd, addr); +	pud_t *pud = pud_offset(p4d, addr);  	if (pud_none(*pud)) {  		void *p = vmemmap_alloc_block(PAGE_SIZE, node);  		if (!p) @@ -208,6 +208,18 @@ pud_t * __meminit vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node)  	return pud;  } +p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node) +{ +	p4d_t *p4d = p4d_offset(pgd, addr); +	if (p4d_none(*p4d)) { +		void *p = vmemmap_alloc_block(PAGE_SIZE, node); +		if (!p) +			return NULL; +		p4d_populate(&init_mm, p4d, p); +	} +	return p4d; +} +  pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)  {  	pgd_t *pgd = pgd_offset_k(addr); @@ -225,6 +237,7 @@ int __meminit vmemmap_populate_basepages(unsigned long start,  {  	unsigned long addr = start;  	pgd_t *pgd; +	p4d_t *p4d;  	pud_t *pud;  	pmd_t *pmd;  	pte_t *pte; @@ -233,7 +246,10 @@ int __meminit vmemmap_populate_basepages(unsigned long start,  		pgd = vmemmap_pgd_populate(addr, node);  		if (!pgd)  			return -ENOMEM; -		pud = vmemmap_pud_populate(pgd, addr, node); +		p4d = vmemmap_p4d_populate(pgd, addr, node); +		if (!p4d) +			return -ENOMEM; +		pud = vmemmap_pud_populate(p4d, addr, node);  		if (!pud)  			return -ENOMEM;  		pmd = vmemmap_pmd_populate(pud, addr, node);  | 
