diff options
Diffstat (limited to 'kernel/kexec.c')
| -rw-r--r-- | kernel/kexec.c | 65 | 
1 files changed, 64 insertions, 1 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c index f336e2107f98..ef077fb73155 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c  | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #include <linux/hardirq.h> | 21 | #include <linux/hardirq.h> | 
| 22 | #include <linux/elf.h> | 22 | #include <linux/elf.h> | 
| 23 | #include <linux/elfcore.h> | 23 | #include <linux/elfcore.h> | 
| 24 | #include <linux/utsrelease.h> | 24 | #include <generated/utsrelease.h> | 
| 25 | #include <linux/utsname.h> | 25 | #include <linux/utsname.h> | 
| 26 | #include <linux/numa.h> | 26 | #include <linux/numa.h> | 
| 27 | #include <linux/suspend.h> | 27 | #include <linux/suspend.h> | 
| @@ -31,6 +31,8 @@ | |||
| 31 | #include <linux/cpu.h> | 31 | #include <linux/cpu.h> | 
| 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> | ||
| 35 | #include <linux/kmsg_dump.h> | ||
| 34 | 36 | ||
| 35 | #include <asm/page.h> | 37 | #include <asm/page.h> | 
| 36 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> | 
| @@ -1073,6 +1075,9 @@ void crash_kexec(struct pt_regs *regs) | |||
| 1073 | if (mutex_trylock(&kexec_mutex)) { | 1075 | if (mutex_trylock(&kexec_mutex)) { | 
| 1074 | if (kexec_crash_image) { | 1076 | if (kexec_crash_image) { | 
| 1075 | struct pt_regs fixed_regs; | 1077 | struct pt_regs fixed_regs; | 
| 1078 | |||
| 1079 | kmsg_dump(KMSG_DUMP_KEXEC); | ||
| 1080 | |||
| 1076 | crash_setup_regs(&fixed_regs, regs); | 1081 | crash_setup_regs(&fixed_regs, regs); | 
| 1077 | crash_save_vmcoreinfo(); | 1082 | crash_save_vmcoreinfo(); | 
| 1078 | machine_crash_shutdown(&fixed_regs); | 1083 | machine_crash_shutdown(&fixed_regs); | 
| @@ -1082,6 +1087,64 @@ void crash_kexec(struct pt_regs *regs) | |||
| 1082 | } | 1087 | } | 
| 1083 | } | 1088 | } | 
| 1084 | 1089 | ||
| 1090 | size_t crash_get_memory_size(void) | ||
| 1091 | { | ||
| 1092 | size_t size; | ||
| 1093 | mutex_lock(&kexec_mutex); | ||
| 1094 | size = crashk_res.end - crashk_res.start + 1; | ||
| 1095 | mutex_unlock(&kexec_mutex); | ||
| 1096 | return size; | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | static void free_reserved_phys_range(unsigned long begin, unsigned long end) | ||
| 1100 | { | ||
| 1101 | unsigned long addr; | ||
| 1102 | |||
| 1103 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
| 1104 | ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT)); | ||
| 1105 | init_page_count(pfn_to_page(addr >> PAGE_SHIFT)); | ||
| 1106 | free_page((unsigned long)__va(addr)); | ||
| 1107 | totalram_pages++; | ||
| 1108 | } | ||
| 1109 | } | ||
| 1110 | |||
| 1111 | int crash_shrink_memory(unsigned long new_size) | ||
| 1112 | { | ||
| 1113 | int ret = 0; | ||
| 1114 | unsigned long start, end; | ||
| 1115 | |||
| 1116 | mutex_lock(&kexec_mutex); | ||
| 1117 | |||
| 1118 | if (kexec_crash_image) { | ||
| 1119 | ret = -ENOENT; | ||
| 1120 | goto unlock; | ||
| 1121 | } | ||
| 1122 | start = crashk_res.start; | ||
| 1123 | end = crashk_res.end; | ||
| 1124 | |||
| 1125 | if (new_size >= end - start + 1) { | ||
| 1126 | ret = -EINVAL; | ||
| 1127 | if (new_size == end - start + 1) | ||
| 1128 | ret = 0; | ||
| 1129 | goto unlock; | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | start = roundup(start, PAGE_SIZE); | ||
| 1133 | end = roundup(start + new_size, PAGE_SIZE); | ||
| 1134 | |||
| 1135 | free_reserved_phys_range(end, crashk_res.end); | ||
| 1136 | |||
| 1137 | if (start == end) { | ||
| 1138 | crashk_res.end = end; | ||
| 1139 | release_resource(&crashk_res); | ||
| 1140 | } else | ||
| 1141 | crashk_res.end = end - 1; | ||
| 1142 | |||
| 1143 | unlock: | ||
| 1144 | mutex_unlock(&kexec_mutex); | ||
| 1145 | return ret; | ||
| 1146 | } | ||
| 1147 | |||
| 1085 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, | 1148 | static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, | 
| 1086 | size_t data_len) | 1149 | size_t data_len) | 
| 1087 | { | 1150 | { | 
