Skip to content

Commit

Permalink
kexec: introduce a protection mechanism for the crashkernel reserved …
Browse files Browse the repository at this point in the history
…memory

For the cases that some kernel (module) path stamps the crash reserved
memory(already mapped by the kernel) where has been loaded the second
kernel data, the kdump kernel will probably fail to boot when panic
happens (or even not happens) leaving the culprit at large, this is
unacceptable.

The patch introduces a mechanism for detecting such cases:

1) After each crash kexec loading, it simply marks the reserved memory
   regions readonly since we no longer access it after that.  When someone
   stamps the region, the first kernel will panic and trigger the kdump.
   The weak arch_kexec_protect_crashkres() is introduced to do the actual
   protection.

2) To allow multiple loading, once 1) was done we also need to remark
   the reserved memory to readwrite each time a system call related to
   kdump is made.  The weak arch_kexec_unprotect_crashkres() is introduced
   to do the actual protection.

The architecture can make its specific implementation by overriding
arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres().

Signed-off-by: Xunlei Pang <[email protected]>
Cc: Eric Biederman <[email protected]>
Cc: Dave Young <[email protected]>
Cc: Minfei Huang <[email protected]>
Cc: Vivek Goyal <[email protected]>
Cc: Baoquan He <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Xunlei Pang authored and torvalds committed May 24, 2016
1 parent 9eb8a65 commit 9b492cf
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/linux/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ int __weak arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr,
Elf_Shdr *sechdrs, unsigned int relsec);
int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
unsigned int relsec);
void arch_kexec_protect_crashkres(void);
void arch_kexec_unprotect_crashkres(void);

#else /* !CONFIG_KEXEC_CORE */
struct pt_regs;
Expand Down
9 changes: 8 additions & 1 deletion kernel/kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,12 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
return -EBUSY;

dest_image = &kexec_image;
if (flags & KEXEC_ON_CRASH)
if (flags & KEXEC_ON_CRASH) {
dest_image = &kexec_crash_image;
if (kexec_crash_image)
arch_kexec_unprotect_crashkres();
}

if (nr_segments > 0) {
unsigned long i;

Expand Down Expand Up @@ -211,6 +215,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
image = xchg(dest_image, image);

out:
if ((flags & KEXEC_ON_CRASH) && kexec_crash_image)
arch_kexec_protect_crashkres();

mutex_unlock(&kexec_mutex);
kimage_free(image);

Expand Down
6 changes: 6 additions & 0 deletions kernel/kexec_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1563,3 +1563,9 @@ void __weak crash_map_reserved_pages(void)

void __weak crash_unmap_reserved_pages(void)
{}

void __weak arch_kexec_protect_crashkres(void)
{}

void __weak arch_kexec_unprotect_crashkres(void)
{}
8 changes: 7 additions & 1 deletion kernel/kexec_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,11 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
return -EBUSY;

dest_image = &kexec_image;
if (flags & KEXEC_FILE_ON_CRASH)
if (flags & KEXEC_FILE_ON_CRASH) {
dest_image = &kexec_crash_image;
if (kexec_crash_image)
arch_kexec_unprotect_crashkres();
}

if (flags & KEXEC_FILE_UNLOAD)
goto exchange;
Expand Down Expand Up @@ -324,6 +327,9 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
exchange:
image = xchg(dest_image, image);
out:
if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image)
arch_kexec_protect_crashkres();

mutex_unlock(&kexec_mutex);
kimage_free(image);
return ret;
Expand Down

0 comments on commit 9b492cf

Please sign in to comment.