aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/vmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/mm/vmem.c')
-rw-r--r--arch/s390/mm/vmem.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 1bd51d840484..fb9c5a85aa56 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -73,6 +73,8 @@ static void __init_refok *vmem_alloc_pages(unsigned int order)
73 return alloc_bootmem_pages((1 << order) * PAGE_SIZE); 73 return alloc_bootmem_pages((1 << order) * PAGE_SIZE);
74} 74}
75 75
76#define vmem_pud_alloc() ({ BUG(); ((pud_t *) NULL); })
77
76static inline pmd_t *vmem_pmd_alloc(void) 78static inline pmd_t *vmem_pmd_alloc(void)
77{ 79{
78 pmd_t *pmd = NULL; 80 pmd_t *pmd = NULL;
@@ -103,6 +105,7 @@ static int vmem_add_range(unsigned long start, unsigned long size)
103{ 105{
104 unsigned long address; 106 unsigned long address;
105 pgd_t *pg_dir; 107 pgd_t *pg_dir;
108 pud_t *pu_dir;
106 pmd_t *pm_dir; 109 pmd_t *pm_dir;
107 pte_t *pt_dir; 110 pte_t *pt_dir;
108 pte_t pte; 111 pte_t pte;
@@ -111,13 +114,21 @@ static int vmem_add_range(unsigned long start, unsigned long size)
111 for (address = start; address < start + size; address += PAGE_SIZE) { 114 for (address = start; address < start + size; address += PAGE_SIZE) {
112 pg_dir = pgd_offset_k(address); 115 pg_dir = pgd_offset_k(address);
113 if (pgd_none(*pg_dir)) { 116 if (pgd_none(*pg_dir)) {
117 pu_dir = vmem_pud_alloc();
118 if (!pu_dir)
119 goto out;
120 pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
121 }
122
123 pu_dir = pud_offset(pg_dir, address);
124 if (pud_none(*pu_dir)) {
114 pm_dir = vmem_pmd_alloc(); 125 pm_dir = vmem_pmd_alloc();
115 if (!pm_dir) 126 if (!pm_dir)
116 goto out; 127 goto out;
117 pgd_populate_kernel(&init_mm, pg_dir, pm_dir); 128 pud_populate_kernel(&init_mm, pu_dir, pm_dir);
118 } 129 }
119 130
120 pm_dir = pmd_offset(pg_dir, address); 131 pm_dir = pmd_offset(pu_dir, address);
121 if (pmd_none(*pm_dir)) { 132 if (pmd_none(*pm_dir)) {
122 pt_dir = vmem_pte_alloc(); 133 pt_dir = vmem_pte_alloc();
123 if (!pt_dir) 134 if (!pt_dir)
@@ -143,6 +154,7 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
143{ 154{
144 unsigned long address; 155 unsigned long address;
145 pgd_t *pg_dir; 156 pgd_t *pg_dir;
157 pud_t *pu_dir;
146 pmd_t *pm_dir; 158 pmd_t *pm_dir;
147 pte_t *pt_dir; 159 pte_t *pt_dir;
148 pte_t pte; 160 pte_t pte;
@@ -150,9 +162,10 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
150 pte_val(pte) = _PAGE_TYPE_EMPTY; 162 pte_val(pte) = _PAGE_TYPE_EMPTY;
151 for (address = start; address < start + size; address += PAGE_SIZE) { 163 for (address = start; address < start + size; address += PAGE_SIZE) {
152 pg_dir = pgd_offset_k(address); 164 pg_dir = pgd_offset_k(address);
153 if (pgd_none(*pg_dir)) 165 pu_dir = pud_offset(pg_dir, address);
166 if (pud_none(*pu_dir))
154 continue; 167 continue;
155 pm_dir = pmd_offset(pg_dir, address); 168 pm_dir = pmd_offset(pu_dir, address);
156 if (pmd_none(*pm_dir)) 169 if (pmd_none(*pm_dir))
157 continue; 170 continue;
158 pt_dir = pte_offset_kernel(pm_dir, address); 171 pt_dir = pte_offset_kernel(pm_dir, address);
@@ -169,6 +182,7 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
169 unsigned long address, start_addr, end_addr; 182 unsigned long address, start_addr, end_addr;
170 struct page *map_start, *map_end; 183 struct page *map_start, *map_end;
171 pgd_t *pg_dir; 184 pgd_t *pg_dir;
185 pud_t *pu_dir;
172 pmd_t *pm_dir; 186 pmd_t *pm_dir;
173 pte_t *pt_dir; 187 pte_t *pt_dir;
174 pte_t pte; 188 pte_t pte;
@@ -183,13 +197,21 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
183 for (address = start_addr; address < end_addr; address += PAGE_SIZE) { 197 for (address = start_addr; address < end_addr; address += PAGE_SIZE) {
184 pg_dir = pgd_offset_k(address); 198 pg_dir = pgd_offset_k(address);
185 if (pgd_none(*pg_dir)) { 199 if (pgd_none(*pg_dir)) {
200 pu_dir = vmem_pud_alloc();
201 if (!pu_dir)
202 goto out;
203 pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
204 }
205
206 pu_dir = pud_offset(pg_dir, address);
207 if (pud_none(*pu_dir)) {
186 pm_dir = vmem_pmd_alloc(); 208 pm_dir = vmem_pmd_alloc();
187 if (!pm_dir) 209 if (!pm_dir)
188 goto out; 210 goto out;
189 pgd_populate_kernel(&init_mm, pg_dir, pm_dir); 211 pud_populate_kernel(&init_mm, pu_dir, pm_dir);
190 } 212 }
191 213
192 pm_dir = pmd_offset(pg_dir, address); 214 pm_dir = pmd_offset(pu_dir, address);
193 if (pmd_none(*pm_dir)) { 215 if (pmd_none(*pm_dir)) {
194 pt_dir = vmem_pte_alloc(); 216 pt_dir = vmem_pte_alloc();
195 if (!pt_dir) 217 if (!pt_dir)