|
@@ -143,6 +143,32 @@ static inline void resume_init_first_level_page_table(pgd_t *pg_dir)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+static int set_up_temporary_text_mapping(pgd_t *pgd_base)
|
|
|
+{
|
|
|
+ pgd_t *pgd;
|
|
|
+ pmd_t *pmd;
|
|
|
+ pte_t *pte;
|
|
|
+
|
|
|
+ pgd = pgd_base + pgd_index(restore_jump_address);
|
|
|
+
|
|
|
+ pmd = resume_one_md_table_init(pgd);
|
|
|
+ if (!pmd)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ if (boot_cpu_has(X86_FEATURE_PSE)) {
|
|
|
+ set_pmd(pmd + pmd_index(restore_jump_address),
|
|
|
+ __pmd((jump_address_phys & PMD_MASK) | pgprot_val(PAGE_KERNEL_LARGE_EXEC)));
|
|
|
+ } else {
|
|
|
+ pte = resume_one_page_table_init(pmd);
|
|
|
+ if (!pte)
|
|
|
+ return -ENOMEM;
|
|
|
+ set_pte(pte + pte_index(restore_jump_address),
|
|
|
+ __pte((jump_address_phys & PAGE_MASK) | pgprot_val(PAGE_KERNEL_EXEC)));
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
asmlinkage int swsusp_arch_resume(void)
|
|
|
{
|
|
|
int error;
|
|
@@ -152,6 +178,11 @@ asmlinkage int swsusp_arch_resume(void)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
resume_init_first_level_page_table(resume_pg_dir);
|
|
|
+
|
|
|
+ error = set_up_temporary_text_mapping(resume_pg_dir);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+
|
|
|
error = resume_physical_mapping_init(resume_pg_dir);
|
|
|
if (error)
|
|
|
return error;
|