Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 106167
b: refs/heads/master
c: 89081d1
h: refs/heads/master
i:
  106165: 88adefa
  106163: eea65cd
  106159: 9c12095
v: v3
  • Loading branch information
Huang Ying authored and Linus Torvalds committed Jul 26, 2008
1 parent 6a3e913 commit a3d0957
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3ab83521378268044a448113c6aa9a9e245f4d2f
refs/heads/master: 89081d17f7bb81d89fa1aa9b70f821c5cf4d39e9
5 changes: 3 additions & 2 deletions trunk/arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1282,9 +1282,10 @@ config CRASH_DUMP
config KEXEC_JUMP
bool "kexec jump (EXPERIMENTAL)"
depends on EXPERIMENTAL
depends on KEXEC && PM_SLEEP && X86_32
depends on KEXEC && HIBERNATION && X86_32
help
Invoke code in physical address mode via KEXEC
Jump between original kernel and kexeced kernel and invoke
code in physical address mode via KEXEC

config PHYSICAL_START
hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
Expand Down
12 changes: 12 additions & 0 deletions trunk/arch/x86/kernel/machine_kexec_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ void machine_kexec(struct kimage *image)
/* Interrupts aren't acceptable while we reboot */
local_irq_disable();

if (image->preserve_context) {
#ifdef CONFIG_X86_IO_APIC
/* We need to put APICs in legacy mode so that we can
* get timer interrupts in second kernel. kexec/kdump
* paths already have calls to disable_IO_APIC() in
* one form or other. kexec jump path also need
* one.
*/
disable_IO_APIC();
#endif
}

control_page = page_address(image->control_code_page);
memcpy(control_page, relocate_kernel, PAGE_SIZE/2);

Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,4 +278,6 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e)
}
#endif

extern struct mutex pm_mutex;

#endif /* _LINUX_SUSPEND_H */
39 changes: 39 additions & 0 deletions trunk/kernel/kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
#include <linux/numa.h>
#include <linux/suspend.h>
#include <linux/device.h>
#include <linux/freezer.h>
#include <linux/pm.h>
#include <linux/cpu.h>
#include <linux/console.h>

#include <asm/page.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -1441,7 +1445,31 @@ int kernel_kexec(void)

if (kexec_image->preserve_context) {
#ifdef CONFIG_KEXEC_JUMP
mutex_lock(&pm_mutex);
pm_prepare_console();
error = freeze_processes();
if (error) {
error = -EBUSY;
goto Restore_console;
}
suspend_console();
error = device_suspend(PMSG_FREEZE);
if (error)
goto Resume_console;
error = disable_nonboot_cpus();
if (error)
goto Resume_devices;
local_irq_disable();
/* At this point, device_suspend() has been called,
* but *not* device_power_down(). We *must*
* device_power_down() now. Otherwise, drivers for
* some devices (e.g. interrupt controllers) become
* desynchronized with the actual state of the
* hardware at resume time, and evil weirdness ensues.
*/
error = device_power_down(PMSG_FREEZE);
if (error)
goto Enable_irqs;
save_processor_state();
#endif
} else {
Expand All @@ -1459,7 +1487,18 @@ int kernel_kexec(void)
if (kexec_image->preserve_context) {
#ifdef CONFIG_KEXEC_JUMP
restore_processor_state();
device_power_up(PMSG_RESTORE);
Enable_irqs:
local_irq_enable();
enable_nonboot_cpus();
Resume_devices:
device_resume(PMSG_RESTORE);
Resume_console:
resume_console();
thaw_processes();
Restore_console:
pm_restore_console();
mutex_unlock(&pm_mutex);
#endif
}

Expand Down
2 changes: 0 additions & 2 deletions trunk/kernel/power/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ extern int hibernation_platform_enter(void);

extern int pfn_is_nosave(unsigned long);

extern struct mutex pm_mutex;

#define power_attr(_name) \
static struct kobj_attribute _name##_attr = { \
.attr = { \
Expand Down

0 comments on commit a3d0957

Please sign in to comment.