aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/lib/uaccess_pt.c7
-rw-r--r--arch/s390/mm/init.c4
-rw-r--r--arch/s390/mm/vmem.c34
3 files changed, 37 insertions, 8 deletions
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index dc37ea827f4e..7e8efaade2ea 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -18,13 +18,18 @@
18static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr) 18static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
19{ 19{
20 pgd_t *pgd; 20 pgd_t *pgd;
21 pud_t *pud;
21 pmd_t *pmd; 22 pmd_t *pmd;
22 23
23 pgd = pgd_offset(mm, addr); 24 pgd = pgd_offset(mm, addr);
24 if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) 25 if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
25 return NULL; 26 return NULL;
26 27
27 pmd = pmd_offset(pgd, addr); 28 pud = pud_offset(pgd, addr);
29 if (pud_none(*pud) || unlikely(pud_bad(*pud)))
30 return NULL;
31
32 pmd = pmd_offset(pud, addr);
28 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) 33 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
29 return NULL; 34 return NULL;
30 35
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 90ec058aa7db..b234bb4a6da7 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -81,6 +81,7 @@ void show_mem(void)
81static void __init setup_ro_region(void) 81static void __init setup_ro_region(void)
82{ 82{
83 pgd_t *pgd; 83 pgd_t *pgd;
84 pud_t *pud;
84 pmd_t *pmd; 85 pmd_t *pmd;
85 pte_t *pte; 86 pte_t *pte;
86 pte_t new_pte; 87 pte_t new_pte;
@@ -91,7 +92,8 @@ static void __init setup_ro_region(void)
91 92
92 for (; address < end; address += PAGE_SIZE) { 93 for (; address < end; address += PAGE_SIZE) {
93 pgd = pgd_offset_k(address); 94 pgd = pgd_offset_k(address);
94 pmd = pmd_offset(pgd, address); 95 pud = pud_offset(pgd, address);
96 pmd = pmd_offset(pud, address);
95 pte = pte_offset_kernel(pmd, address); 97 pte = pte_offset_kernel(pmd, address);
96 new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO)); 98 new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO));
97 *pte = new_pte; 99 *pte = new_pte;
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)