aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kexec.c')
-rw-r--r--kernel/kexec.c70
1 files changed, 49 insertions, 21 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 296fbc84d659..7b0886786701 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -32,7 +32,6 @@
32#include <linux/console.h> 32#include <linux/console.h>
33#include <linux/vmalloc.h> 33#include <linux/vmalloc.h>
34#include <linux/swap.h> 34#include <linux/swap.h>
35#include <linux/kmsg_dump.h>
36#include <linux/syscore_ops.h> 35#include <linux/syscore_ops.h>
37 36
38#include <asm/page.h> 37#include <asm/page.h>
@@ -498,7 +497,7 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
498 while (hole_end <= crashk_res.end) { 497 while (hole_end <= crashk_res.end) {
499 unsigned long i; 498 unsigned long i;
500 499
501 if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT) 500 if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
502 break; 501 break;
503 if (hole_end > crashk_res.end) 502 if (hole_end > crashk_res.end)
504 break; 503 break;
@@ -999,6 +998,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
999 kimage_free(xchg(&kexec_crash_image, NULL)); 998 kimage_free(xchg(&kexec_crash_image, NULL));
1000 result = kimage_crash_alloc(&image, entry, 999 result = kimage_crash_alloc(&image, entry,
1001 nr_segments, segments); 1000 nr_segments, segments);
1001 crash_map_reserved_pages();
1002 } 1002 }
1003 if (result) 1003 if (result)
1004 goto out; 1004 goto out;
@@ -1015,6 +1015,8 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
1015 goto out; 1015 goto out;
1016 } 1016 }
1017 kimage_terminate(image); 1017 kimage_terminate(image);
1018 if (flags & KEXEC_ON_CRASH)
1019 crash_unmap_reserved_pages();
1018 } 1020 }
1019 /* Install the new kernel, and Uninstall the old */ 1021 /* Install the new kernel, and Uninstall the old */
1020 image = xchg(dest_image, image); 1022 image = xchg(dest_image, image);
@@ -1026,6 +1028,18 @@ out:
1026 return result; 1028 return result;
1027} 1029}
1028 1030
1031/*
1032 * Add and remove page tables for crashkernel memory
1033 *
1034 * Provide an empty default implementation here -- architecture
1035 * code may override this
1036 */
1037void __weak crash_map_reserved_pages(void)
1038{}
1039
1040void __weak crash_unmap_reserved_pages(void)
1041{}
1042
1029#ifdef CONFIG_COMPAT 1043#ifdef CONFIG_COMPAT
1030asmlinkage long compat_sys_kexec_load(unsigned long entry, 1044asmlinkage long compat_sys_kexec_load(unsigned long entry,
1031 unsigned long nr_segments, 1045 unsigned long nr_segments,
@@ -1079,8 +1093,6 @@ void crash_kexec(struct pt_regs *regs)
1079 if (kexec_crash_image) { 1093 if (kexec_crash_image) {
1080 struct pt_regs fixed_regs; 1094 struct pt_regs fixed_regs;
1081 1095
1082 kmsg_dump(KMSG_DUMP_KEXEC);
1083
1084 crash_setup_regs(&fixed_regs, regs); 1096 crash_setup_regs(&fixed_regs, regs);
1085 crash_save_vmcoreinfo(); 1097 crash_save_vmcoreinfo();
1086 machine_crash_shutdown(&fixed_regs); 1098 machine_crash_shutdown(&fixed_regs);
@@ -1117,6 +1129,8 @@ int crash_shrink_memory(unsigned long new_size)
1117{ 1129{
1118 int ret = 0; 1130 int ret = 0;
1119 unsigned long start, end; 1131 unsigned long start, end;
1132 unsigned long old_size;
1133 struct resource *ram_res;
1120 1134
1121 mutex_lock(&kexec_mutex); 1135 mutex_lock(&kexec_mutex);
1122 1136
@@ -1126,23 +1140,37 @@ int crash_shrink_memory(unsigned long new_size)
1126 } 1140 }
1127 start = crashk_res.start; 1141 start = crashk_res.start;
1128 end = crashk_res.end; 1142 end = crashk_res.end;
1143 old_size = (end == 0) ? 0 : end - start + 1;
1144 if (new_size >= old_size) {
1145 ret = (new_size == old_size) ? 0 : -EINVAL;
1146 goto unlock;
1147 }
1129 1148
1130 if (new_size >= end - start + 1) { 1149 ram_res = kzalloc(sizeof(*ram_res), GFP_KERNEL);
1131 ret = -EINVAL; 1150 if (!ram_res) {
1132 if (new_size == end - start + 1) 1151 ret = -ENOMEM;
1133 ret = 0;
1134 goto unlock; 1152 goto unlock;
1135 } 1153 }
1136 1154
1137 start = roundup(start, PAGE_SIZE); 1155 start = roundup(start, KEXEC_CRASH_MEM_ALIGN);
1138 end = roundup(start + new_size, PAGE_SIZE); 1156 end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN);
1139 1157
1158 crash_map_reserved_pages();
1140 crash_free_reserved_phys_range(end, crashk_res.end); 1159 crash_free_reserved_phys_range(end, crashk_res.end);
1141 1160
1142 if ((start == end) && (crashk_res.parent != NULL)) 1161 if ((start == end) && (crashk_res.parent != NULL))
1143 release_resource(&crashk_res); 1162 release_resource(&crashk_res);
1163
1164 ram_res->start = end;
1165 ram_res->end = crashk_res.end;
1166 ram_res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
1167 ram_res->name = "System RAM";
1168
1144 crashk_res.end = end - 1; 1169 crashk_res.end = end - 1;
1145 1170
1171 insert_resource(&iomem_resource, ram_res);
1172 crash_unmap_reserved_pages();
1173
1146unlock: 1174unlock:
1147 mutex_unlock(&kexec_mutex); 1175 mutex_unlock(&kexec_mutex);
1148 return ret; 1176 return ret;
@@ -1380,24 +1408,23 @@ int __init parse_crashkernel(char *cmdline,
1380} 1408}
1381 1409
1382 1410
1383 1411static void update_vmcoreinfo_note(void)
1384void crash_save_vmcoreinfo(void)
1385{ 1412{
1386 u32 *buf; 1413 u32 *buf = vmcoreinfo_note;
1387 1414
1388 if (!vmcoreinfo_size) 1415 if (!vmcoreinfo_size)
1389 return; 1416 return;
1390
1391 vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds());
1392
1393 buf = (u32 *)vmcoreinfo_note;
1394
1395 buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data, 1417 buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
1396 vmcoreinfo_size); 1418 vmcoreinfo_size);
1397
1398 final_note(buf); 1419 final_note(buf);
1399} 1420}
1400 1421
1422void crash_save_vmcoreinfo(void)
1423{
1424 vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds());
1425 update_vmcoreinfo_note();
1426}
1427
1401void vmcoreinfo_append_str(const char *fmt, ...) 1428void vmcoreinfo_append_str(const char *fmt, ...)
1402{ 1429{
1403 va_list args; 1430 va_list args;
@@ -1483,6 +1510,7 @@ static int __init crash_save_vmcoreinfo_init(void)
1483 VMCOREINFO_NUMBER(PG_swapcache); 1510 VMCOREINFO_NUMBER(PG_swapcache);
1484 1511
1485 arch_crash_save_vmcoreinfo(); 1512 arch_crash_save_vmcoreinfo();
1513 update_vmcoreinfo_note();
1486 1514
1487 return 0; 1515 return 0;
1488} 1516}
@@ -1506,7 +1534,7 @@ int kernel_kexec(void)
1506 1534
1507#ifdef CONFIG_KEXEC_JUMP 1535#ifdef CONFIG_KEXEC_JUMP
1508 if (kexec_image->preserve_context) { 1536 if (kexec_image->preserve_context) {
1509 mutex_lock(&pm_mutex); 1537 lock_system_sleep();
1510 pm_prepare_console(); 1538 pm_prepare_console();
1511 error = freeze_processes(); 1539 error = freeze_processes();
1512 if (error) { 1540 if (error) {
@@ -1559,7 +1587,7 @@ int kernel_kexec(void)
1559 thaw_processes(); 1587 thaw_processes();
1560 Restore_console: 1588 Restore_console:
1561 pm_restore_console(); 1589 pm_restore_console();
1562 mutex_unlock(&pm_mutex); 1590 unlock_system_sleep();
1563 } 1591 }
1564#endif 1592#endif
1565 1593