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 { | |||
27 | 27 | ||
28 | static LIST_HEAD(mem_segs); | 28 | static LIST_HEAD(mem_segs); |
29 | 29 | ||
30 | static pud_t *vmem_pud_alloc(void) | 30 | static void __ref *vmem_alloc_pages(unsigned int order) |
31 | { | ||
32 | if (slab_is_available()) | ||
33 | return (void *)__get_free_pages(GFP_KERNEL, order); | ||
34 | return alloc_bootmem_pages((1 << order) * PAGE_SIZE); | ||
35 | } | ||
36 | |||
37 | static inline pud_t *vmem_pud_alloc(void) | ||
31 | { | 38 | { |
32 | pud_t *pud = NULL; | 39 | pud_t *pud = NULL; |
33 | 40 | ||
34 | #ifdef CONFIG_64BIT | 41 | #ifdef CONFIG_64BIT |
35 | pud = vmemmap_alloc_block(PAGE_SIZE * 4, 0); | 42 | pud = vmem_alloc_pages(2); |
36 | if (!pud) | 43 | if (!pud) |
37 | return NULL; | 44 | return NULL; |
38 | clear_table((unsigned long *) pud, _REGION3_ENTRY_EMPTY, PAGE_SIZE * 4); | 45 | clear_table((unsigned long *) pud, _REGION3_ENTRY_EMPTY, PAGE_SIZE * 4); |
@@ -40,12 +47,12 @@ static pud_t *vmem_pud_alloc(void) | |||
40 | return pud; | 47 | return pud; |
41 | } | 48 | } |
42 | 49 | ||
43 | static pmd_t *vmem_pmd_alloc(void) | 50 | static inline pmd_t *vmem_pmd_alloc(void) |
44 | { | 51 | { |
45 | pmd_t *pmd = NULL; | 52 | pmd_t *pmd = NULL; |
46 | 53 | ||
47 | #ifdef CONFIG_64BIT | 54 | #ifdef CONFIG_64BIT |
48 | pmd = vmemmap_alloc_block(PAGE_SIZE * 4, 0); | 55 | pmd = vmem_alloc_pages(2); |
49 | if (!pmd) | 56 | if (!pmd) |
50 | return NULL; | 57 | return NULL; |
51 | clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE * 4); | 58 | 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) | |||
207 | if (pte_none(*pt_dir)) { | 214 | if (pte_none(*pt_dir)) { |
208 | unsigned long new_page; | 215 | unsigned long new_page; |
209 | 216 | ||
210 | new_page =__pa(vmemmap_alloc_block(PAGE_SIZE, 0)); | 217 | new_page =__pa(vmem_alloc_pages(0)); |
211 | if (!new_page) | 218 | if (!new_page) |
212 | goto out; | 219 | goto out; |
213 | pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL); | 220 | pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL); |
214 | *pt_dir = pte; | 221 | *pt_dir = pte; |
215 | } | 222 | } |
216 | } | 223 | } |
224 | memset(start, 0, nr * sizeof(struct page)); | ||
217 | ret = 0; | 225 | ret = 0; |
218 | out: | 226 | out: |
219 | flush_tlb_kernel_range(start_addr, end_addr); | 227 | flush_tlb_kernel_range(start_addr, end_addr); |
@@ -228,7 +236,7 @@ static int insert_memory_segment(struct memory_segment *seg) | |||
228 | { | 236 | { |
229 | struct memory_segment *tmp; | 237 | struct memory_segment *tmp; |
230 | 238 | ||
231 | if (seg->start + seg->size >= VMEM_MAX_PHYS || | 239 | if (seg->start + seg->size > VMEM_MAX_PHYS || |
232 | seg->start + seg->size < seg->start) | 240 | seg->start + seg->size < seg->start) |
233 | return -ERANGE; | 241 | return -ERANGE; |
234 | 242 | ||