aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/suspend_64.c39
1 files changed, 6 insertions, 33 deletions
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c
index db284ef44d53..2e5efaaf8800 100644
--- a/arch/x86/kernel/suspend_64.c
+++ b/arch/x86/kernel/suspend_64.c
@@ -192,42 +192,25 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en
192 return 0; 192 return 0;
193} 193}
194 194
195static int res_kernel_text_pud_init(pud_t *pud, unsigned long start)
196{
197 pmd_t *pmd;
198 unsigned long paddr;
199
200 pmd = (pmd_t *)get_safe_page(GFP_ATOMIC);
201 if (!pmd)
202 return -ENOMEM;
203 set_pud(pud + pud_index(start), __pud(__pa(pmd) | _KERNPG_TABLE));
204 for (paddr = 0; paddr < KERNEL_TEXT_SIZE; pmd++, paddr += PMD_SIZE) {
205 unsigned long pe;
206
207 pe = __PAGE_KERNEL_LARGE_EXEC | _PAGE_GLOBAL | paddr;
208 pe &= __supported_pte_mask;
209 set_pmd(pmd, __pmd(pe));
210 }
211
212 return 0;
213}
214
215static int set_up_temporary_mappings(void) 195static int set_up_temporary_mappings(void)
216{ 196{
217 unsigned long start, end, next; 197 unsigned long start, end, next;
218 pud_t *pud;
219 int error; 198 int error;
220 199
221 temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC); 200 temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC);
222 if (!temp_level4_pgt) 201 if (!temp_level4_pgt)
223 return -ENOMEM; 202 return -ENOMEM;
224 203
204 /* It is safe to reuse the original kernel mapping */
205 set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
206 init_level4_pgt[pgd_index(__START_KERNEL_map)]);
207
225 /* Set up the direct mapping from scratch */ 208 /* Set up the direct mapping from scratch */
226 start = (unsigned long)pfn_to_kaddr(0); 209 start = (unsigned long)pfn_to_kaddr(0);
227 end = (unsigned long)pfn_to_kaddr(end_pfn); 210 end = (unsigned long)pfn_to_kaddr(end_pfn);
228 211
229 for (; start < end; start = next) { 212 for (; start < end; start = next) {
230 pud = (pud_t *)get_safe_page(GFP_ATOMIC); 213 pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC);
231 if (!pud) 214 if (!pud)
232 return -ENOMEM; 215 return -ENOMEM;
233 next = start + PGDIR_SIZE; 216 next = start + PGDIR_SIZE;
@@ -238,17 +221,7 @@ static int set_up_temporary_mappings(void)
238 set_pgd(temp_level4_pgt + pgd_index(start), 221 set_pgd(temp_level4_pgt + pgd_index(start),
239 mk_kernel_pgd(__pa(pud))); 222 mk_kernel_pgd(__pa(pud)));
240 } 223 }
241 224 return 0;
242 /* Set up the kernel text mapping from scratch */
243 pud = (pud_t *)get_safe_page(GFP_ATOMIC);
244 if (!pud)
245 return -ENOMEM;
246 error = res_kernel_text_pud_init(pud, __START_KERNEL_map);
247 if (!error)
248 set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
249 __pgd(__pa(pud) | _PAGE_TABLE));
250
251 return error;
252} 225}
253 226
254int swsusp_arch_resume(void) 227int swsusp_arch_resume(void)