diff options
Diffstat (limited to 'arch/s390/mm/vmem.c')
| -rw-r--r-- | arch/s390/mm/vmem.c | 20 | 
1 files changed, 14 insertions, 6 deletions
| diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index ea2804808f39..e4868bfc672f 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -27,12 +27,19 @@ struct memory_segment {  static LIST_HEAD(mem_segs); -static pud_t *vmem_pud_alloc(void) +static void __ref *vmem_alloc_pages(unsigned int order) +{ +	if (slab_is_available()) +		return (void *)__get_free_pages(GFP_KERNEL, order); +	return alloc_bootmem_pages((1 << order) * PAGE_SIZE); +} + +static inline pud_t *vmem_pud_alloc(void)  {  	pud_t *pud = NULL;  #ifdef CONFIG_64BIT -	pud = vmemmap_alloc_block(PAGE_SIZE * 4, 0); +	pud = vmem_alloc_pages(2);  	if (!pud)  		return NULL;  	clear_table((unsigned long *) pud, _REGION3_ENTRY_EMPTY, PAGE_SIZE * 4); @@ -40,12 +47,12 @@ static pud_t *vmem_pud_alloc(void)  	return pud;  } -static pmd_t *vmem_pmd_alloc(void) +static inline pmd_t *vmem_pmd_alloc(void)  {  	pmd_t *pmd = NULL;  #ifdef CONFIG_64BIT -	pmd = vmemmap_alloc_block(PAGE_SIZE * 4, 0); +	pmd = vmem_alloc_pages(2);  	if (!pmd)  		return NULL;  	clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE * 4); @@ -207,13 +214,14 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)  		if (pte_none(*pt_dir)) {  			unsigned long new_page; -			new_page =__pa(vmemmap_alloc_block(PAGE_SIZE, 0)); +			new_page =__pa(vmem_alloc_pages(0));  			if (!new_page)  				goto out;  			pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL);  			*pt_dir = pte;  		}  	} +	memset(start, 0, nr * sizeof(struct page));  	ret = 0;  out:  	flush_tlb_kernel_range(start_addr, end_addr); @@ -228,7 +236,7 @@ static int insert_memory_segment(struct memory_segment *seg)  {  	struct memory_segment *tmp; -	if (seg->start + seg->size >= VMEM_MAX_PHYS || +	if (seg->start + seg->size > VMEM_MAX_PHYS ||  	    seg->start + seg->size < seg->start)  		return -ERANGE; | 
