aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kexec.c')
-rw-r--r--kernel/kexec.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 6db42ff8d520..a0d920915b38 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -24,6 +24,8 @@
24#include <linux/utsrelease.h> 24#include <linux/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>
28#include <linux/device.h>
27 29
28#include <asm/page.h> 30#include <asm/page.h>
29#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -242,6 +244,12 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
242 goto out; 244 goto out;
243 } 245 }
244 246
247 image->swap_page = kimage_alloc_control_pages(image, 0);
248 if (!image->swap_page) {
249 printk(KERN_ERR "Could not allocate swap buffer\n");
250 goto out;
251 }
252
245 result = 0; 253 result = 0;
246 out: 254 out:
247 if (result == 0) 255 if (result == 0)
@@ -986,6 +994,8 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
986 if (result) 994 if (result)
987 goto out; 995 goto out;
988 996
997 if (flags & KEXEC_PRESERVE_CONTEXT)
998 image->preserve_context = 1;
989 result = machine_kexec_prepare(image); 999 result = machine_kexec_prepare(image);
990 if (result) 1000 if (result)
991 goto out; 1001 goto out;
@@ -1411,3 +1421,50 @@ static int __init crash_save_vmcoreinfo_init(void)
1411} 1421}
1412 1422
1413module_init(crash_save_vmcoreinfo_init) 1423module_init(crash_save_vmcoreinfo_init)
1424
1425/**
1426 * kernel_kexec - reboot the system
1427 *
1428 * Move into place and start executing a preloaded standalone
1429 * executable. If nothing was preloaded return an error.
1430 */
1431int kernel_kexec(void)
1432{
1433 int error = 0;
1434
1435 if (xchg(&kexec_lock, 1))
1436 return -EBUSY;
1437 if (!kexec_image) {
1438 error = -EINVAL;
1439 goto Unlock;
1440 }
1441
1442 if (kexec_image->preserve_context) {
1443#ifdef CONFIG_KEXEC_JUMP
1444 local_irq_disable();
1445 save_processor_state();
1446#endif
1447 } else {
1448 blocking_notifier_call_chain(&reboot_notifier_list,
1449 SYS_RESTART, NULL);
1450 system_state = SYSTEM_RESTART;
1451 device_shutdown();
1452 sysdev_shutdown();
1453 printk(KERN_EMERG "Starting new kernel\n");
1454 machine_shutdown();
1455 }
1456
1457 machine_kexec(kexec_image);
1458
1459 if (kexec_image->preserve_context) {
1460#ifdef CONFIG_KEXEC_JUMP
1461 restore_processor_state();
1462 local_irq_enable();
1463#endif
1464 }
1465
1466 Unlock:
1467 xchg(&kexec_lock, 0);
1468
1469 return error;
1470}