diff options
Diffstat (limited to 'arch/x86/kernel/suspend_64.c')
-rw-r--r-- | arch/x86/kernel/suspend_64.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c index 2e5efaaf8800..09199511c256 100644 --- a/arch/x86/kernel/suspend_64.c +++ b/arch/x86/kernel/suspend_64.c | |||
@@ -17,9 +17,26 @@ | |||
17 | /* References to section boundaries */ | 17 | /* References to section boundaries */ |
18 | extern const void __nosave_begin, __nosave_end; | 18 | extern const void __nosave_begin, __nosave_end; |
19 | 19 | ||
20 | static void fix_processor_context(void); | ||
21 | |||
20 | struct saved_context saved_context; | 22 | struct saved_context saved_context; |
21 | 23 | ||
22 | void __save_processor_state(struct saved_context *ctxt) | 24 | /** |
25 | * __save_processor_state - save CPU registers before creating a | ||
26 | * hibernation image and before restoring the memory state from it | ||
27 | * @ctxt - structure to store the registers contents in | ||
28 | * | ||
29 | * NOTE: If there is a CPU register the modification of which by the | ||
30 | * boot kernel (ie. the kernel used for loading the hibernation image) | ||
31 | * might affect the operations of the restored target kernel (ie. the one | ||
32 | * saved in the hibernation image), then its contents must be saved by this | ||
33 | * function. In other words, if kernel A is hibernated and different | ||
34 | * kernel B is used for loading the hibernation image into memory, the | ||
35 | * kernel A's __save_processor_state() function must save all registers | ||
36 | * needed by kernel A, so that it can operate correctly after the resume | ||
37 | * regardless of what kernel B does in the meantime. | ||
38 | */ | ||
39 | static void __save_processor_state(struct saved_context *ctxt) | ||
23 | { | 40 | { |
24 | kernel_fpu_begin(); | 41 | kernel_fpu_begin(); |
25 | 42 | ||
@@ -69,7 +86,12 @@ static void do_fpu_end(void) | |||
69 | kernel_fpu_end(); | 86 | kernel_fpu_end(); |
70 | } | 87 | } |
71 | 88 | ||
72 | void __restore_processor_state(struct saved_context *ctxt) | 89 | /** |
90 | * __restore_processor_state - restore the contents of CPU registers saved | ||
91 | * by __save_processor_state() | ||
92 | * @ctxt - structure to load the registers contents from | ||
93 | */ | ||
94 | static void __restore_processor_state(struct saved_context *ctxt) | ||
73 | { | 95 | { |
74 | /* | 96 | /* |
75 | * control registers | 97 | * control registers |
@@ -113,14 +135,14 @@ void restore_processor_state(void) | |||
113 | __restore_processor_state(&saved_context); | 135 | __restore_processor_state(&saved_context); |
114 | } | 136 | } |
115 | 137 | ||
116 | void fix_processor_context(void) | 138 | static void fix_processor_context(void) |
117 | { | 139 | { |
118 | int cpu = smp_processor_id(); | 140 | int cpu = smp_processor_id(); |
119 | struct tss_struct *t = &per_cpu(init_tss, cpu); | 141 | struct tss_struct *t = &per_cpu(init_tss, cpu); |
120 | 142 | ||
121 | set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ | 143 | set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ |
122 | 144 | ||
123 | cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9; | 145 | get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9; |
124 | 146 | ||
125 | syscall_init(); /* This sets MSR_*STAR and related */ | 147 | syscall_init(); /* This sets MSR_*STAR and related */ |
126 | load_TR_desc(); /* This does ltr */ | 148 | load_TR_desc(); /* This does ltr */ |