diff options
-rw-r--r-- | include/linux/kexec.h | 2 | ||||
-rw-r--r-- | kernel/kexec.c | 9 | ||||
-rw-r--r-- | kernel/kexec_core.c | 6 | ||||
-rw-r--r-- | kernel/kexec_file.c | 8 |
4 files changed, 23 insertions, 2 deletions
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 2cc643c6e870..643ff4a3fbf6 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -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; diff --git a/kernel/kexec.c b/kernel/kexec.c index ee70aef5cd81..b44cb3f5a15c 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -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; @@ -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); diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index d5d408252992..48b73cc8e425 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -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) +{} diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index c72d2ff5896e..503bc2d348e5 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -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; @@ -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; |