aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2011-10-30 10:16:43 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-10-30 10:16:42 -0400
commit558df7209e7997275f6b8ad37737494cf2da1512 (patch)
tree0f10dac15f4c2266d7d49f02ae4920863497dc32 /kernel/kexec.c
parentd38593f9387055566b782d00d38d9a347a96e7d9 (diff)
[S390] kdump: Add infrastructure for unmapping crashkernel memory
This patch introduces a mechanism that allows architecture backends to remove page tables for the crashkernel memory. This can protect the loaded kdump kernel from being overwritten by broken kernel code. Two new functions crash_map_reserved_pages() and crash_unmap_reserved_pages() are added that can be implemented by architecture code. The crash_map_reserved_pages() function is called before and crash_unmap_reserved_pages() after the crashkernel segments are loaded. The functions are also called in crash_shrink_memory() to create/remove page tables when the crashkernel memory size is reduced. To support architectures that have large pages this patch also introduces a new define KEXEC_CRASH_MEM_ALIGN. The crashkernel start and size must always be aligned with KEXEC_CRASH_MEM_ALIGN. Cc: Andrew Morton <akpm@linux-foundation.org> Acked-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'kernel/kexec.c')
-rw-r--r--kernel/kexec.c21
1 files changed, 19 insertions, 2 deletions
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 */
1038void __weak crash_map_reserved_pages(void)
1039{}
1040
1041void __weak crash_unmap_reserved_pages(void)
1042{}
1043
1029#ifdef CONFIG_COMPAT 1044#ifdef CONFIG_COMPAT
1030asmlinkage long compat_sys_kexec_load(unsigned long entry, 1045asmlinkage 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
1146unlock: 1163unlock:
1147 mutex_unlock(&kexec_mutex); 1164 mutex_unlock(&kexec_mutex);