diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 31 |
1 files changed, 8 insertions, 23 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 0c9d3fa1f5ff..c01858090a98 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -301,26 +301,6 @@ void kernel_restart(char *cmd) | |||
301 | } | 301 | } |
302 | EXPORT_SYMBOL_GPL(kernel_restart); | 302 | EXPORT_SYMBOL_GPL(kernel_restart); |
303 | 303 | ||
304 | /** | ||
305 | * kernel_kexec - reboot the system | ||
306 | * | ||
307 | * Move into place and start executing a preloaded standalone | ||
308 | * executable. If nothing was preloaded return an error. | ||
309 | */ | ||
310 | static void kernel_kexec(void) | ||
311 | { | ||
312 | #ifdef CONFIG_KEXEC | ||
313 | struct kimage *image; | ||
314 | image = xchg(&kexec_image, NULL); | ||
315 | if (!image) | ||
316 | return; | ||
317 | kernel_restart_prepare(NULL); | ||
318 | printk(KERN_EMERG "Starting new kernel\n"); | ||
319 | machine_shutdown(); | ||
320 | machine_kexec(image); | ||
321 | #endif | ||
322 | } | ||
323 | |||
324 | static void kernel_shutdown_prepare(enum system_states state) | 304 | static void kernel_shutdown_prepare(enum system_states state) |
325 | { | 305 | { |
326 | blocking_notifier_call_chain(&reboot_notifier_list, | 306 | blocking_notifier_call_chain(&reboot_notifier_list, |
@@ -425,10 +405,15 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user | |||
425 | kernel_restart(buffer); | 405 | kernel_restart(buffer); |
426 | break; | 406 | break; |
427 | 407 | ||
408 | #ifdef CONFIG_KEXEC | ||
428 | case LINUX_REBOOT_CMD_KEXEC: | 409 | case LINUX_REBOOT_CMD_KEXEC: |
429 | kernel_kexec(); | 410 | { |
430 | unlock_kernel(); | 411 | int ret; |
431 | return -EINVAL; | 412 | ret = kernel_kexec(); |
413 | unlock_kernel(); | ||
414 | return ret; | ||
415 | } | ||
416 | #endif | ||
432 | 417 | ||
433 | #ifdef CONFIG_HIBERNATION | 418 | #ifdef CONFIG_HIBERNATION |
434 | case LINUX_REBOOT_CMD_SW_SUSPEND: | 419 | case LINUX_REBOOT_CMD_SW_SUSPEND: |