aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2014-08-08 17:25:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 18:57:32 -0400
commit255aedd90e3e804fb52e1a71636a3b22cf12f81b (patch)
tree5b25989bec463c43a82d159c8b285fdbbb57eb03 /kernel/kexec.c
parentdabe78628dd886c4b71971d1d78f1cecc674b760 (diff)
kexec: use common function for kimage_normal_alloc() and kimage_crash_alloc()
kimage_normal_alloc() and kimage_crash_alloc() are doing lot of similar things and differ only little. So instead of having two separate functions create a common function kimage_alloc_init() and pass it the "flags" argument which tells whether it is normal kexec or kexec_on_panic. And this function should be able to deal with both the cases. This consolidation also helps later where we can use a common function kimage_file_alloc_init() to handle normal and crash cases for new file based kexec syscall. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Cc: Borislav Petkov <bp@suse.de> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Eric Biederman <ebiederm@xmission.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Greg Kroah-Hartman <greg@kroah.com> Cc: Dave Young <dyoung@redhat.com> Cc: WANG Chao <chaowang@redhat.com> Cc: Baoquan He <bhe@redhat.com> Cc: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/kexec.c')
-rw-r--r--kernel/kexec.c105
1 files changed, 34 insertions, 71 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 062e5567750e..bfdda316697d 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -261,12 +261,20 @@ static struct kimage *do_kimage_alloc_init(void)
261 261
262static void kimage_free_page_list(struct list_head *list); 262static void kimage_free_page_list(struct list_head *list);
263 263
264static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, 264static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
265 unsigned long nr_segments, 265 unsigned long nr_segments,
266 struct kexec_segment __user *segments) 266 struct kexec_segment __user *segments,
267 unsigned long flags)
267{ 268{
268 int result; 269 int ret;
269 struct kimage *image; 270 struct kimage *image;
271 bool kexec_on_panic = flags & KEXEC_ON_CRASH;
272
273 if (kexec_on_panic) {
274 /* Verify we have a valid entry point */
275 if ((entry < crashk_res.start) || (entry > crashk_res.end))
276 return -EADDRNOTAVAIL;
277 }
270 278
271 /* Allocate and initialize a controlling structure */ 279 /* Allocate and initialize a controlling structure */
272 image = do_kimage_alloc_init(); 280 image = do_kimage_alloc_init();
@@ -275,20 +283,26 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
275 283
276 image->start = entry; 284 image->start = entry;
277 285
278 result = copy_user_segment_list(image, nr_segments, segments); 286 ret = copy_user_segment_list(image, nr_segments, segments);
279 if (result) 287 if (ret)
280 goto out_free_image; 288 goto out_free_image;
281 289
282 result = sanity_check_segment_list(image); 290 ret = sanity_check_segment_list(image);
283 if (result) 291 if (ret)
284 goto out_free_image; 292 goto out_free_image;
285 293
294 /* Enable the special crash kernel control page allocation policy. */
295 if (kexec_on_panic) {
296 image->control_page = crashk_res.start;
297 image->type = KEXEC_TYPE_CRASH;
298 }
299
286 /* 300 /*
287 * Find a location for the control code buffer, and add it 301 * Find a location for the control code buffer, and add it
288 * the vector of segments so that it's pages will also be 302 * the vector of segments so that it's pages will also be
289 * counted as destination pages. 303 * counted as destination pages.
290 */ 304 */
291 result = -ENOMEM; 305 ret = -ENOMEM;
292 image->control_code_page = kimage_alloc_control_pages(image, 306 image->control_code_page = kimage_alloc_control_pages(image,
293 get_order(KEXEC_CONTROL_PAGE_SIZE)); 307 get_order(KEXEC_CONTROL_PAGE_SIZE));
294 if (!image->control_code_page) { 308 if (!image->control_code_page) {
@@ -296,10 +310,12 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
296 goto out_free_image; 310 goto out_free_image;
297 } 311 }
298 312
299 image->swap_page = kimage_alloc_control_pages(image, 0); 313 if (!kexec_on_panic) {
300 if (!image->swap_page) { 314 image->swap_page = kimage_alloc_control_pages(image, 0);
301 pr_err("Could not allocate swap buffer\n"); 315 if (!image->swap_page) {
302 goto out_free_control_pages; 316 pr_err("Could not allocate swap buffer\n");
317 goto out_free_control_pages;
318 }
303 } 319 }
304 320
305 *rimage = image; 321 *rimage = image;
@@ -308,60 +324,7 @@ out_free_control_pages:
308 kimage_free_page_list(&image->control_pages); 324 kimage_free_page_list(&image->control_pages);
309out_free_image: 325out_free_image:
310 kfree(image); 326 kfree(image);
311 return result; 327 return ret;
312}
313
314static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
315 unsigned long nr_segments,
316 struct kexec_segment __user *segments)
317{
318 int result;
319 struct kimage *image;
320
321 /* Verify we have a valid entry point */
322 if ((entry < crashk_res.start) || (entry > crashk_res.end))
323 return -EADDRNOTAVAIL;
324
325 /* Allocate and initialize a controlling structure */
326 image = do_kimage_alloc_init();
327 if (!image)
328 return -ENOMEM;
329
330 image->start = entry;
331
332 /* Enable the special crash kernel control page
333 * allocation policy.
334 */
335 image->control_page = crashk_res.start;
336 image->type = KEXEC_TYPE_CRASH;
337
338 result = copy_user_segment_list(image, nr_segments, segments);
339 if (result)
340 goto out_free_image;
341
342 result = sanity_check_segment_list(image);
343 if (result)
344 goto out_free_image;
345
346 /*
347 * Find a location for the control code buffer, and add
348 * the vector of segments so that it's pages will also be
349 * counted as destination pages.
350 */
351 result = -ENOMEM;
352 image->control_code_page = kimage_alloc_control_pages(image,
353 get_order(KEXEC_CONTROL_PAGE_SIZE));
354 if (!image->control_code_page) {
355 pr_err("Could not allocate control_code_buffer\n");
356 goto out_free_image;
357 }
358
359 *rimage = image;
360 return 0;
361
362out_free_image:
363 kfree(image);
364 return result;
365} 328}
366 329
367static int kimage_is_destination_range(struct kimage *image, 330static int kimage_is_destination_range(struct kimage *image,
@@ -1004,16 +967,16 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
1004 967
1005 /* Loading another kernel to reboot into */ 968 /* Loading another kernel to reboot into */
1006 if ((flags & KEXEC_ON_CRASH) == 0) 969 if ((flags & KEXEC_ON_CRASH) == 0)
1007 result = kimage_normal_alloc(&image, entry, 970 result = kimage_alloc_init(&image, entry, nr_segments,
1008 nr_segments, segments); 971 segments, flags);
1009 /* Loading another kernel to switch to if this one crashes */ 972 /* Loading another kernel to switch to if this one crashes */
1010 else if (flags & KEXEC_ON_CRASH) { 973 else if (flags & KEXEC_ON_CRASH) {
1011 /* Free any current crash dump kernel before 974 /* Free any current crash dump kernel before
1012 * we corrupt it. 975 * we corrupt it.
1013 */ 976 */
1014 kimage_free(xchg(&kexec_crash_image, NULL)); 977 kimage_free(xchg(&kexec_crash_image, NULL));
1015 result = kimage_crash_alloc(&image, entry, 978 result = kimage_alloc_init(&image, entry, nr_segments,
1016 nr_segments, segments); 979 segments, flags);
1017 crash_map_reserved_pages(); 980 crash_map_reserved_pages();
1018 } 981 }
1019 if (result) 982 if (result)