Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9d7e36b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: hibernate: handle allocation failures"

parents 3ae9cf1b 5ac0bb2f
Loading
Loading
Loading
Loading
+32 −27
Original line number Diff line number Diff line
@@ -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.
@@ -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.
@@ -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));