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

Commit 1e5768ae authored by Xunlei Pang's avatar Xunlei Pang Committed by Linus Torvalds
Browse files

kexec: provide arch_kexec_protect(unprotect)_crashkres()



Implement the protection method for the crash kernel memory reservation
for the 64-bit x86 kdump.

Signed-off-by: default avatarXunlei Pang <xlpang@redhat.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Dave Young <dyoung@redhat.com>
Cc: Minfei Huang <mhuang@redhat.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9b492cf5
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -538,3 +538,48 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
	return -ENOEXEC;
}
#endif /* CONFIG_KEXEC_FILE */

static int
kexec_mark_range(unsigned long start, unsigned long end, bool protect)
{
	struct page *page;
	unsigned int nr_pages;

	/*
	 * For physical range: [start, end]. We must skip the unassigned
	 * crashk resource with zero-valued "end" member.
	 */
	if (!end || start > end)
		return 0;

	page = pfn_to_page(start >> PAGE_SHIFT);
	nr_pages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
	if (protect)
		return set_pages_ro(page, nr_pages);
	else
		return set_pages_rw(page, nr_pages);
}

static void kexec_mark_crashkres(bool protect)
{
	unsigned long control;

	kexec_mark_range(crashk_low_res.start, crashk_low_res.end, protect);

	/* Don't touch the control code page used in crash_kexec().*/
	control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page));
	/* Control code page is located in the 2nd page. */
	kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect);
	control += KEXEC_CONTROL_PAGE_SIZE;
	kexec_mark_range(control, crashk_res.end, protect);
}

void arch_kexec_protect_crashkres(void)
{
	kexec_mark_crashkres(true);
}

void arch_kexec_unprotect_crashkres(void)
{
	kexec_mark_crashkres(false);
}