diff options
-rw-r--r-- | include/linux/kexec.h | 6 | ||||
-rw-r--r-- | kernel/kexec.c | 21 |
2 files changed, 25 insertions, 2 deletions
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 07d9aba75562..fe45136b32cc 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h | |||
@@ -37,6 +37,10 @@ | |||
37 | #define KEXEC_CRASH_CONTROL_MEMORY_LIMIT KEXEC_CONTROL_MEMORY_LIMIT | 37 | #define KEXEC_CRASH_CONTROL_MEMORY_LIMIT KEXEC_CONTROL_MEMORY_LIMIT |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifndef KEXEC_CRASH_MEM_ALIGN | ||
41 | #define KEXEC_CRASH_MEM_ALIGN PAGE_SIZE | ||
42 | #endif | ||
43 | |||
40 | #define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4) | 44 | #define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4) |
41 | #define KEXEC_CORE_NOTE_NAME "CORE" | 45 | #define KEXEC_CORE_NOTE_NAME "CORE" |
42 | #define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4) | 46 | #define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4) |
@@ -133,6 +137,8 @@ extern void crash_kexec(struct pt_regs *); | |||
133 | int kexec_should_crash(struct task_struct *); | 137 | int kexec_should_crash(struct task_struct *); |
134 | void crash_save_cpu(struct pt_regs *regs, int cpu); | 138 | void crash_save_cpu(struct pt_regs *regs, int cpu); |
135 | void crash_save_vmcoreinfo(void); | 139 | void crash_save_vmcoreinfo(void); |
140 | void crash_map_reserved_pages(void); | ||
141 | void crash_unmap_reserved_pages(void); | ||
136 | void arch_crash_save_vmcoreinfo(void); | 142 | void arch_crash_save_vmcoreinfo(void); |
137 | void vmcoreinfo_append_str(const char *fmt, ...) | 143 | void vmcoreinfo_append_str(const char *fmt, ...) |
138 | __attribute__ ((format (printf, 1, 2))); | 144 | __attribute__ ((format (printf, 1, 2))); |
diff --git a/kernel/kexec.c b/kernel/kexec.c index d3b8a4ceb90b..dc7bc0829286 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -999,6 +999,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, | |||
999 | kimage_free(xchg(&kexec_crash_image, NULL)); | 999 | kimage_free(xchg(&kexec_crash_image, NULL)); |
1000 | result = kimage_crash_alloc(&image, entry, | 1000 | result = kimage_crash_alloc(&image, entry, |
1001 | nr_segments, segments); | 1001 | nr_segments, segments); |
1002 | crash_map_reserved_pages(); | ||
1002 | } | 1003 | } |
1003 | if (result) | 1004 | if (result) |
1004 | goto out; | 1005 | goto out; |
@@ -1015,6 +1016,8 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, | |||
1015 | goto out; | 1016 | goto out; |
1016 | } | 1017 | } |
1017 | kimage_terminate(image); | 1018 | kimage_terminate(image); |
1019 | if (flags & KEXEC_ON_CRASH) | ||
1020 | crash_unmap_reserved_pages(); | ||
1018 | } | 1021 | } |
1019 | /* Install the new kernel, and Uninstall the old */ | 1022 | /* Install the new kernel, and Uninstall the old */ |
1020 | image = xchg(dest_image, image); | 1023 | image = xchg(dest_image, image); |
@@ -1026,6 +1029,18 @@ out: | |||
1026 | return result; | 1029 | return result; |
1027 | } | 1030 | } |
1028 | 1031 | ||
1032 | /* | ||
1033 | * Add and remove page tables for crashkernel memory | ||
1034 | * | ||
1035 | * Provide an empty default implementation here -- architecture | ||
1036 | * code may override this | ||
1037 | */ | ||
1038 | void __weak crash_map_reserved_pages(void) | ||
1039 | {} | ||
1040 | |||
1041 | void __weak crash_unmap_reserved_pages(void) | ||
1042 | {} | ||
1043 | |||
1029 | #ifdef CONFIG_COMPAT | 1044 | #ifdef CONFIG_COMPAT |
1030 | asmlinkage long compat_sys_kexec_load(unsigned long entry, | 1045 | asmlinkage long compat_sys_kexec_load(unsigned long entry, |
1031 | unsigned long nr_segments, | 1046 | unsigned long nr_segments, |
@@ -1134,14 +1149,16 @@ int crash_shrink_memory(unsigned long new_size) | |||
1134 | goto unlock; | 1149 | goto unlock; |
1135 | } | 1150 | } |
1136 | 1151 | ||
1137 | start = roundup(start, PAGE_SIZE); | 1152 | start = roundup(start, KEXEC_CRASH_MEM_ALIGN); |
1138 | end = roundup(start + new_size, PAGE_SIZE); | 1153 | end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN); |
1139 | 1154 | ||
1155 | crash_map_reserved_pages(); | ||
1140 | crash_free_reserved_phys_range(end, crashk_res.end); | 1156 | crash_free_reserved_phys_range(end, crashk_res.end); |
1141 | 1157 | ||
1142 | if ((start == end) && (crashk_res.parent != NULL)) | 1158 | if ((start == end) && (crashk_res.parent != NULL)) |
1143 | release_resource(&crashk_res); | 1159 | release_resource(&crashk_res); |
1144 | crashk_res.end = end - 1; | 1160 | crashk_res.end = end - 1; |
1161 | crash_unmap_reserved_pages(); | ||
1145 | 1162 | ||
1146 | unlock: | 1163 | unlock: |
1147 | mutex_unlock(&kexec_mutex); | 1164 | mutex_unlock(&kexec_mutex); |