aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/power/cpu_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/power/cpu_32.c')
-rw-r--r--arch/x86/power/cpu_32.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/arch/x86/power/cpu_32.c b/arch/x86/power/cpu_32.c
index 294e78baff75..29b9c0a1ca62 100644
--- a/arch/x86/power/cpu_32.c
+++ b/arch/x86/power/cpu_32.c
@@ -27,8 +27,6 @@ unsigned long saved_context_esi, saved_context_edi;
27unsigned long saved_context_eflags; 27unsigned long saved_context_eflags;
28#else 28#else
29/* CONFIG_X86_64 */ 29/* CONFIG_X86_64 */
30static void fix_processor_context(void);
31
32struct saved_context saved_context; 30struct saved_context saved_context;
33#endif 31#endif
34 32
@@ -136,6 +134,11 @@ static void fix_processor_context(void)
136 * similar stupidity. 134 * similar stupidity.
137 */ 135 */
138 136
137#ifdef CONFIG_X86_64
138 get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
139
140 syscall_init(); /* This sets MSR_*STAR and related */
141#endif
139 load_TR_desc(); /* This does ltr */ 142 load_TR_desc(); /* This does ltr */
140 load_LDT(&current->active_mm->context); /* This does lldt */ 143 load_LDT(&current->active_mm->context); /* This does lldt */
141 144
@@ -143,6 +146,7 @@ static void fix_processor_context(void)
143 * Now maybe reload the debug registers 146 * Now maybe reload the debug registers
144 */ 147 */
145 if (current->thread.debugreg7) { 148 if (current->thread.debugreg7) {
149#ifdef CONFIG_X86_32
146 set_debugreg(current->thread.debugreg0, 0); 150 set_debugreg(current->thread.debugreg0, 0);
147 set_debugreg(current->thread.debugreg1, 1); 151 set_debugreg(current->thread.debugreg1, 1);
148 set_debugreg(current->thread.debugreg2, 2); 152 set_debugreg(current->thread.debugreg2, 2);
@@ -150,18 +154,40 @@ static void fix_processor_context(void)
150 /* no 4 and 5 */ 154 /* no 4 and 5 */
151 set_debugreg(current->thread.debugreg6, 6); 155 set_debugreg(current->thread.debugreg6, 6);
152 set_debugreg(current->thread.debugreg7, 7); 156 set_debugreg(current->thread.debugreg7, 7);
157#else
158 /* CONFIG_X86_64 */
159 loaddebug(&current->thread, 0);
160 loaddebug(&current->thread, 1);
161 loaddebug(&current->thread, 2);
162 loaddebug(&current->thread, 3);
163 /* no 4 and 5 */
164 loaddebug(&current->thread, 6);
165 loaddebug(&current->thread, 7);
166#endif
153 } 167 }
154 168
155} 169}
156 170
171/**
172 * __restore_processor_state - restore the contents of CPU registers saved
173 * by __save_processor_state()
174 * @ctxt - structure to load the registers contents from
175 */
157static void __restore_processor_state(struct saved_context *ctxt) 176static void __restore_processor_state(struct saved_context *ctxt)
158{ 177{
159 /* 178 /*
160 * control registers 179 * control registers
161 */ 180 */
162 /* cr4 was introduced in the Pentium CPU */ 181 /* cr4 was introduced in the Pentium CPU */
182#ifdef CONFIG_X86_32
163 if (ctxt->cr4) 183 if (ctxt->cr4)
164 write_cr4(ctxt->cr4); 184 write_cr4(ctxt->cr4);
185#else
186/* CONFIG X86_64 */
187 wrmsrl(MSR_EFER, ctxt->efer);
188 write_cr8(ctxt->cr8);
189 write_cr4(ctxt->cr4);
190#endif
165 write_cr3(ctxt->cr3); 191 write_cr3(ctxt->cr3);
166 write_cr2(ctxt->cr2); 192 write_cr2(ctxt->cr2);
167 write_cr0(ctxt->cr0); 193 write_cr0(ctxt->cr0);
@@ -170,12 +196,19 @@ static void __restore_processor_state(struct saved_context *ctxt)
170 * now restore the descriptor tables to their proper values 196 * now restore the descriptor tables to their proper values
171 * ltr is done i fix_processor_context(). 197 * ltr is done i fix_processor_context().
172 */ 198 */
199#ifdef CONFIG_X86_32
173 load_gdt(&ctxt->gdt); 200 load_gdt(&ctxt->gdt);
174 load_idt(&ctxt->idt); 201 load_idt(&ctxt->idt);
202#else
203/* CONFIG_X86_64 */
204 load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
205 load_idt((const struct desc_ptr *)&ctxt->idt_limit);
206#endif
175 207
176 /* 208 /*
177 * segment registers 209 * segment registers
178 */ 210 */
211#ifdef CONFIG_X86_32
179 loadsegment(es, ctxt->es); 212 loadsegment(es, ctxt->es);
180 loadsegment(fs, ctxt->fs); 213 loadsegment(fs, ctxt->fs);
181 loadsegment(gs, ctxt->gs); 214 loadsegment(gs, ctxt->gs);
@@ -186,6 +219,18 @@ static void __restore_processor_state(struct saved_context *ctxt)
186 */ 219 */
187 if (boot_cpu_has(X86_FEATURE_SEP)) 220 if (boot_cpu_has(X86_FEATURE_SEP))
188 enable_sep_cpu(); 221 enable_sep_cpu();
222#else
223/* CONFIG_X86_64 */
224 asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds));
225 asm volatile ("movw %0, %%es" :: "r" (ctxt->es));
226 asm volatile ("movw %0, %%fs" :: "r" (ctxt->fs));
227 load_gs_index(ctxt->gs);
228 asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss));
229
230 wrmsrl(MSR_FS_BASE, ctxt->fs_base);
231 wrmsrl(MSR_GS_BASE, ctxt->gs_base);
232 wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base);
233#endif
189 234
190 /* 235 /*
191 * restore XCR0 for xsave capable cpu's. 236 * restore XCR0 for xsave capable cpu's.
@@ -194,9 +239,13 @@ static void __restore_processor_state(struct saved_context *ctxt)
194 xsetbv(XCR_XFEATURE_ENABLED_MASK, pcntxt_mask); 239 xsetbv(XCR_XFEATURE_ENABLED_MASK, pcntxt_mask);
195 240
196 fix_processor_context(); 241 fix_processor_context();
242
197 do_fpu_end(); 243 do_fpu_end();
198 mtrr_ap_init(); 244 mtrr_ap_init();
245
246#ifdef CONFIG_X86_32
199 mcheck_init(&boot_cpu_data); 247 mcheck_init(&boot_cpu_data);
248#endif
200} 249}
201 250
202/* Needed by apm.c */ 251/* Needed by apm.c */
@@ -204,4 +253,6 @@ void restore_processor_state(void)
204{ 253{
205 __restore_processor_state(&saved_context); 254 __restore_processor_state(&saved_context);
206} 255}
256#ifdef CONFIG_X86_32
207EXPORT_SYMBOL(restore_processor_state); 257EXPORT_SYMBOL(restore_processor_state);
258#endif