Loading arch/arm64/kernel/hibernate.c +32 −27 Original line number Diff line number Diff line Loading @@ -398,6 +398,38 @@ int swsusp_arch_resume(void) void __noreturn (*hibernate_exit)(phys_addr_t, phys_addr_t, void *, void *, phys_addr_t, phys_addr_t); /* * Restoring the memory image will overwrite the ttbr1 page tables. * Create a second copy of just the linear map, and use this when * restoring. */ tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); if (!tmp_pg_dir) { pr_err("Failed to allocate memory for temporary page tables."); rc = -ENOMEM; goto out; } rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0); if (rc) goto out; /* * Since we only copied the linear map, we need to find restore_pblist's * linear map address. */ lm_restore_pblist = LMADDR(restore_pblist); /* * We need a zero page that is zero before & after resume in order to * to break before make on the ttbr1 page tables. */ zero_page = (void *)get_safe_page(GFP_ATOMIC); if (!zero_page) { pr_err("Failed to allocate zero page."); rc = -ENOMEM; goto out; } /* * Locate the exit code in the bottom-but-one page, so that *NULL * still has disastrous affects. Loading @@ -423,27 +455,6 @@ int swsusp_arch_resume(void) */ __flush_dcache_area(hibernate_exit, exit_size); /* * Restoring the memory image will overwrite the ttbr1 page tables. * Create a second copy of just the linear map, and use this when * restoring. */ tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); if (!tmp_pg_dir) { pr_err("Failed to allocate memory for temporary page tables."); rc = -ENOMEM; goto out; } rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0); if (rc) goto out; /* * Since we only copied the linear map, we need to find restore_pblist's * linear map address. */ lm_restore_pblist = LMADDR(restore_pblist); /* * KASLR will cause the el2 vectors to be in a different location in * the resumed kernel. Load hibernate's temporary copy into el2. Loading @@ -458,12 +469,6 @@ int swsusp_arch_resume(void) __hyp_set_vectors(el2_vectors); } /* * We need a zero page that is zero before & after resume in order to * to break before make on the ttbr1 page tables. */ zero_page = (void *)get_safe_page(GFP_ATOMIC); hibernate_exit(virt_to_phys(tmp_pg_dir), resume_hdr.ttbr1_el1, resume_hdr.reenter_kernel, lm_restore_pblist, resume_hdr.__hyp_stub_vectors, virt_to_phys(zero_page)); Loading Loading
arch/arm64/kernel/hibernate.c +32 −27 Original line number Diff line number Diff line Loading @@ -398,6 +398,38 @@ int swsusp_arch_resume(void) void __noreturn (*hibernate_exit)(phys_addr_t, phys_addr_t, void *, void *, phys_addr_t, phys_addr_t); /* * Restoring the memory image will overwrite the ttbr1 page tables. * Create a second copy of just the linear map, and use this when * restoring. */ tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); if (!tmp_pg_dir) { pr_err("Failed to allocate memory for temporary page tables."); rc = -ENOMEM; goto out; } rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0); if (rc) goto out; /* * Since we only copied the linear map, we need to find restore_pblist's * linear map address. */ lm_restore_pblist = LMADDR(restore_pblist); /* * We need a zero page that is zero before & after resume in order to * to break before make on the ttbr1 page tables. */ zero_page = (void *)get_safe_page(GFP_ATOMIC); if (!zero_page) { pr_err("Failed to allocate zero page."); rc = -ENOMEM; goto out; } /* * Locate the exit code in the bottom-but-one page, so that *NULL * still has disastrous affects. Loading @@ -423,27 +455,6 @@ int swsusp_arch_resume(void) */ __flush_dcache_area(hibernate_exit, exit_size); /* * Restoring the memory image will overwrite the ttbr1 page tables. * Create a second copy of just the linear map, and use this when * restoring. */ tmp_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); if (!tmp_pg_dir) { pr_err("Failed to allocate memory for temporary page tables."); rc = -ENOMEM; goto out; } rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0); if (rc) goto out; /* * Since we only copied the linear map, we need to find restore_pblist's * linear map address. */ lm_restore_pblist = LMADDR(restore_pblist); /* * KASLR will cause the el2 vectors to be in a different location in * the resumed kernel. Load hibernate's temporary copy into el2. Loading @@ -458,12 +469,6 @@ int swsusp_arch_resume(void) __hyp_set_vectors(el2_vectors); } /* * We need a zero page that is zero before & after resume in order to * to break before make on the ttbr1 page tables. */ zero_page = (void *)get_safe_page(GFP_ATOMIC); hibernate_exit(virt_to_phys(tmp_pg_dir), resume_hdr.ttbr1_el1, resume_hdr.reenter_kernel, lm_restore_pblist, resume_hdr.__hyp_stub_vectors, virt_to_phys(zero_page)); Loading