diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/lib/uaccess_pt.c | 7 | ||||
-rw-r--r-- | arch/s390/mm/init.c | 4 | ||||
-rw-r--r-- | arch/s390/mm/vmem.c | 34 |
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 @@ | |||
18 | static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr) | 18 | static 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) | |||
81 | static void __init setup_ro_region(void) | 81 | static 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 | |||
76 | static inline pmd_t *vmem_pmd_alloc(void) | 78 | static 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) |