diff options
Diffstat (limited to 'arch/x86/power/cpu_32.c')
-rw-r--r-- | arch/x86/power/cpu_32.c | 55 |
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; | |||
27 | unsigned long saved_context_eflags; | 27 | unsigned long saved_context_eflags; |
28 | #else | 28 | #else |
29 | /* CONFIG_X86_64 */ | 29 | /* CONFIG_X86_64 */ |
30 | static void fix_processor_context(void); | ||
31 | |||
32 | struct saved_context saved_context; | 30 | struct 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(¤t->active_mm->context); /* This does lldt */ | 143 | load_LDT(¤t->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(¤t->thread, 0); | ||
160 | loaddebug(¤t->thread, 1); | ||
161 | loaddebug(¤t->thread, 2); | ||
162 | loaddebug(¤t->thread, 3); | ||
163 | /* no 4 and 5 */ | ||
164 | loaddebug(¤t->thread, 6); | ||
165 | loaddebug(¤t->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 | */ | ||
157 | static void __restore_processor_state(struct saved_context *ctxt) | 176 | static 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 | ||
207 | EXPORT_SYMBOL(restore_processor_state); | 257 | EXPORT_SYMBOL(restore_processor_state); |
258 | #endif | ||