Skip to content

Commit cb24e1e

Browse files
Xunlei PangAlex Shi
authored andcommitted
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: Xunlei 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> (cherry picked from commit 1e5768ae7500e7ce6eb73e1b263574d5c19606cf) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent 4b97cec commit cb24e1e

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

arch/x86/kernel/machine_kexec_64.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,3 +536,48 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
536536
return -ENOEXEC;
537537
}
538538
#endif /* CONFIG_KEXEC_FILE */
539+
540+
static int
541+
kexec_mark_range(unsigned long start, unsigned long end, bool protect)
542+
{
543+
struct page *page;
544+
unsigned int nr_pages;
545+
546+
/*
547+
* For physical range: [start, end]. We must skip the unassigned
548+
* crashk resource with zero-valued "end" member.
549+
*/
550+
if (!end || start > end)
551+
return 0;
552+
553+
page = pfn_to_page(start >> PAGE_SHIFT);
554+
nr_pages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
555+
if (protect)
556+
return set_pages_ro(page, nr_pages);
557+
else
558+
return set_pages_rw(page, nr_pages);
559+
}
560+
561+
static void kexec_mark_crashkres(bool protect)
562+
{
563+
unsigned long control;
564+
565+
kexec_mark_range(crashk_low_res.start, crashk_low_res.end, protect);
566+
567+
/* Don't touch the control code page used in crash_kexec().*/
568+
control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page));
569+
/* Control code page is located in the 2nd page. */
570+
kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect);
571+
control += KEXEC_CONTROL_PAGE_SIZE;
572+
kexec_mark_range(control, crashk_res.end, protect);
573+
}
574+
575+
void arch_kexec_protect_crashkres(void)
576+
{
577+
kexec_mark_crashkres(true);
578+
}
579+
580+
void arch_kexec_unprotect_crashkres(void)
581+
{
582+
kexec_mark_crashkres(false);
583+
}

0 commit comments

Comments
 (0)