properly save kvm system time msr registers
[qemu-kvm/fedora.git] / target-i386 / machine.c
blob46545088c0b2ada6e175a56b432c8a0ab32002ac
1 #include "hw/hw.h"
2 #include "hw/boards.h"
3 #include "hw/pc.h"
4 #include "hw/isa.h"
5 #include "host-utils.h"
7 #include "exec-all.h"
8 #include "kvm.h"
9 #include "qemu-kvm.h"
11 static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
13 qemu_put_be32(f, dt->selector);
14 qemu_put_betl(f, dt->base);
15 qemu_put_be32(f, dt->limit);
16 qemu_put_be32(f, dt->flags);
19 static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
21 dt->selector = qemu_get_be32(f);
22 dt->base = qemu_get_betl(f);
23 dt->limit = qemu_get_be32(f);
24 dt->flags = qemu_get_be32(f);
27 void cpu_save(QEMUFile *f, void *opaque)
29 CPUState *env = opaque;
30 uint16_t fptag, fpus, fpuc, fpregs_format;
31 uint32_t hflags;
32 int32_t a20_mask;
33 int32_t pending_irq;
34 int i, bit;
36 if (kvm_enabled()) {
37 kvm_save_registers(env);
38 kvm_arch_save_mpstate(env);
41 for(i = 0; i < CPU_NB_REGS; i++)
42 qemu_put_betls(f, &env->regs[i]);
43 qemu_put_betls(f, &env->eip);
44 qemu_put_betls(f, &env->eflags);
45 hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
46 qemu_put_be32s(f, &hflags);
48 /* FPU */
49 fpuc = env->fpuc;
50 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
51 fptag = 0;
52 for(i = 0; i < 8; i++) {
53 fptag |= ((!env->fptags[i]) << i);
56 qemu_put_be16s(f, &fpuc);
57 qemu_put_be16s(f, &fpus);
58 qemu_put_be16s(f, &fptag);
60 #ifdef USE_X86LDOUBLE
61 fpregs_format = 0;
62 #else
63 fpregs_format = 1;
64 #endif
65 qemu_put_be16s(f, &fpregs_format);
67 for(i = 0; i < 8; i++) {
68 #ifdef USE_X86LDOUBLE
70 uint64_t mant;
71 uint16_t exp;
72 /* we save the real CPU data (in case of MMX usage only 'mant'
73 contains the MMX register */
74 cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
75 qemu_put_be64(f, mant);
76 qemu_put_be16(f, exp);
78 #else
79 /* if we use doubles for float emulation, we save the doubles to
80 avoid losing information in case of MMX usage. It can give
81 problems if the image is restored on a CPU where long
82 doubles are used instead. */
83 qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
84 #endif
87 for(i = 0; i < 6; i++)
88 cpu_put_seg(f, &env->segs[i]);
89 cpu_put_seg(f, &env->ldt);
90 cpu_put_seg(f, &env->tr);
91 cpu_put_seg(f, &env->gdt);
92 cpu_put_seg(f, &env->idt);
94 qemu_put_be32s(f, &env->sysenter_cs);
95 qemu_put_betls(f, &env->sysenter_esp);
96 qemu_put_betls(f, &env->sysenter_eip);
98 qemu_put_betls(f, &env->cr[0]);
99 qemu_put_betls(f, &env->cr[2]);
100 qemu_put_betls(f, &env->cr[3]);
101 qemu_put_betls(f, &env->cr[4]);
103 for(i = 0; i < 8; i++)
104 qemu_put_betls(f, &env->dr[i]);
106 /* MMU */
107 a20_mask = (int32_t) env->a20_mask;
108 qemu_put_sbe32s(f, &a20_mask);
110 /* XMM */
111 qemu_put_be32s(f, &env->mxcsr);
112 for(i = 0; i < CPU_NB_REGS; i++) {
113 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
114 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
117 #ifdef TARGET_X86_64
118 qemu_put_be64s(f, &env->efer);
119 qemu_put_be64s(f, &env->star);
120 qemu_put_be64s(f, &env->lstar);
121 qemu_put_be64s(f, &env->cstar);
122 qemu_put_be64s(f, &env->fmask);
123 qemu_put_be64s(f, &env->kernelgsbase);
124 #endif
125 qemu_put_be32s(f, &env->smbase);
126 qemu_put_be64s(f, &env->pat);
127 qemu_put_be32s(f, &env->hflags2);
129 qemu_put_be64s(f, &env->vm_hsave);
130 qemu_put_be64s(f, &env->vm_vmcb);
131 qemu_put_be64s(f, &env->tsc_offset);
132 qemu_put_be64s(f, &env->intercept);
133 qemu_put_be16s(f, &env->intercept_cr_read);
134 qemu_put_be16s(f, &env->intercept_cr_write);
135 qemu_put_be16s(f, &env->intercept_dr_read);
136 qemu_put_be16s(f, &env->intercept_dr_write);
137 qemu_put_be32s(f, &env->intercept_exceptions);
138 qemu_put_8s(f, &env->v_tpr);
140 /* MTRRs */
141 for(i = 0; i < 11; i++)
142 qemu_put_be64s(f, &env->mtrr_fixed[i]);
143 qemu_put_be64s(f, &env->mtrr_deftype);
144 for(i = 0; i < 8; i++) {
145 qemu_put_be64s(f, &env->mtrr_var[i].base);
146 qemu_put_be64s(f, &env->mtrr_var[i].mask);
149 /* KVM-related states */
151 /* There can only be one pending IRQ set in the bitmap at a time, so try
152 to find it and save its number instead (-1 for none). */
153 pending_irq = -1;
154 for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) {
155 if (env->interrupt_bitmap[i]) {
156 bit = ctz64(env->interrupt_bitmap[i]);
157 pending_irq = i * 64 + bit;
158 break;
161 qemu_put_sbe32s(f, &pending_irq);
162 qemu_put_be32s(f, &env->mp_state);
163 qemu_put_be64s(f, &env->tsc);
165 /* MCE */
166 qemu_put_be64s(f, &env->mcg_cap);
167 if (env->mcg_cap && !kvm_enabled()) {
168 qemu_put_be64s(f, &env->mcg_status);
169 qemu_put_be64s(f, &env->mcg_ctl);
170 for (i = 0; i < (env->mcg_cap & 0xff); i++) {
171 qemu_put_be64s(f, &env->mce_banks[4*i]);
172 qemu_put_be64s(f, &env->mce_banks[4*i + 1]);
173 qemu_put_be64s(f, &env->mce_banks[4*i + 2]);
174 qemu_put_be64s(f, &env->mce_banks[4*i + 3]);
178 qemu_put_be64s(f, &env->system_time_msr);
179 qemu_put_be64s(f, &env->wall_clock_msr);
182 #ifdef USE_X86LDOUBLE
183 /* XXX: add that in a FPU generic layer */
184 union x86_longdouble {
185 uint64_t mant;
186 uint16_t exp;
189 #define MANTD1(fp) (fp & ((1LL << 52) - 1))
190 #define EXPBIAS1 1023
191 #define EXPD1(fp) ((fp >> 52) & 0x7FF)
192 #define SIGND1(fp) ((fp >> 32) & 0x80000000)
194 static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
196 int e;
197 /* mantissa */
198 p->mant = (MANTD1(temp) << 11) | (1LL << 63);
199 /* exponent + sign */
200 e = EXPD1(temp) - EXPBIAS1 + 16383;
201 e |= SIGND1(temp) >> 16;
202 p->exp = e;
204 #endif
206 int cpu_load(QEMUFile *f, void *opaque, int version_id)
208 CPUState *env = opaque;
209 int i, guess_mmx;
210 uint32_t hflags;
211 uint16_t fpus, fpuc, fptag, fpregs_format;
212 int32_t a20_mask;
213 int32_t pending_irq;
215 if (version_id < 3 || version_id > CPU_SAVE_VERSION)
216 return -EINVAL;
217 for(i = 0; i < CPU_NB_REGS; i++)
218 qemu_get_betls(f, &env->regs[i]);
219 qemu_get_betls(f, &env->eip);
220 qemu_get_betls(f, &env->eflags);
221 qemu_get_be32s(f, &hflags);
223 qemu_get_be16s(f, &fpuc);
224 qemu_get_be16s(f, &fpus);
225 qemu_get_be16s(f, &fptag);
226 qemu_get_be16s(f, &fpregs_format);
228 /* NOTE: we cannot always restore the FPU state if the image come
229 from a host with a different 'USE_X86LDOUBLE' define. We guess
230 if we are in an MMX state to restore correctly in that case. */
231 guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
232 for(i = 0; i < 8; i++) {
233 uint64_t mant;
234 uint16_t exp;
236 switch(fpregs_format) {
237 case 0:
238 mant = qemu_get_be64(f);
239 exp = qemu_get_be16(f);
240 #ifdef USE_X86LDOUBLE
241 env->fpregs[i].d = cpu_set_fp80(mant, exp);
242 #else
243 /* difficult case */
244 if (guess_mmx)
245 env->fpregs[i].mmx.MMX_Q(0) = mant;
246 else
247 env->fpregs[i].d = cpu_set_fp80(mant, exp);
248 #endif
249 break;
250 case 1:
251 mant = qemu_get_be64(f);
252 #ifdef USE_X86LDOUBLE
254 union x86_longdouble *p;
255 /* difficult case */
256 p = (void *)&env->fpregs[i];
257 if (guess_mmx) {
258 p->mant = mant;
259 p->exp = 0xffff;
260 } else {
261 fp64_to_fp80(p, mant);
264 #else
265 env->fpregs[i].mmx.MMX_Q(0) = mant;
266 #endif
267 break;
268 default:
269 return -EINVAL;
273 env->fpuc = fpuc;
274 /* XXX: restore FPU round state */
275 env->fpstt = (fpus >> 11) & 7;
276 env->fpus = fpus & ~0x3800;
277 fptag ^= 0xff;
278 for(i = 0; i < 8; i++) {
279 env->fptags[i] = (fptag >> i) & 1;
282 for(i = 0; i < 6; i++)
283 cpu_get_seg(f, &env->segs[i]);
284 cpu_get_seg(f, &env->ldt);
285 cpu_get_seg(f, &env->tr);
286 cpu_get_seg(f, &env->gdt);
287 cpu_get_seg(f, &env->idt);
289 qemu_get_be32s(f, &env->sysenter_cs);
290 if (version_id >= 7) {
291 qemu_get_betls(f, &env->sysenter_esp);
292 qemu_get_betls(f, &env->sysenter_eip);
293 } else {
294 env->sysenter_esp = qemu_get_be32(f);
295 env->sysenter_eip = qemu_get_be32(f);
298 qemu_get_betls(f, &env->cr[0]);
299 qemu_get_betls(f, &env->cr[2]);
300 qemu_get_betls(f, &env->cr[3]);
301 qemu_get_betls(f, &env->cr[4]);
303 for(i = 0; i < 8; i++)
304 qemu_get_betls(f, &env->dr[i]);
305 cpu_breakpoint_remove_all(env, BP_CPU);
306 cpu_watchpoint_remove_all(env, BP_CPU);
307 for (i = 0; i < 4; i++)
308 hw_breakpoint_insert(env, i);
310 /* MMU */
311 qemu_get_sbe32s(f, &a20_mask);
312 env->a20_mask = a20_mask;
314 qemu_get_be32s(f, &env->mxcsr);
315 for(i = 0; i < CPU_NB_REGS; i++) {
316 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
317 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
320 #ifdef TARGET_X86_64
321 qemu_get_be64s(f, &env->efer);
322 qemu_get_be64s(f, &env->star);
323 qemu_get_be64s(f, &env->lstar);
324 qemu_get_be64s(f, &env->cstar);
325 qemu_get_be64s(f, &env->fmask);
326 qemu_get_be64s(f, &env->kernelgsbase);
327 #endif
328 if (version_id >= 4) {
329 qemu_get_be32s(f, &env->smbase);
331 if (version_id >= 5) {
332 qemu_get_be64s(f, &env->pat);
333 qemu_get_be32s(f, &env->hflags2);
334 if (version_id < 6)
335 qemu_get_be32s(f, &env->halted);
337 qemu_get_be64s(f, &env->vm_hsave);
338 qemu_get_be64s(f, &env->vm_vmcb);
339 qemu_get_be64s(f, &env->tsc_offset);
340 qemu_get_be64s(f, &env->intercept);
341 qemu_get_be16s(f, &env->intercept_cr_read);
342 qemu_get_be16s(f, &env->intercept_cr_write);
343 qemu_get_be16s(f, &env->intercept_dr_read);
344 qemu_get_be16s(f, &env->intercept_dr_write);
345 qemu_get_be32s(f, &env->intercept_exceptions);
346 qemu_get_8s(f, &env->v_tpr);
349 if (version_id >= 8) {
350 /* MTRRs */
351 for(i = 0; i < 11; i++)
352 qemu_get_be64s(f, &env->mtrr_fixed[i]);
353 qemu_get_be64s(f, &env->mtrr_deftype);
354 for(i = 0; i < 8; i++) {
355 qemu_get_be64s(f, &env->mtrr_var[i].base);
356 qemu_get_be64s(f, &env->mtrr_var[i].mask);
360 if (version_id >= 9) {
361 qemu_get_sbe32s(f, &pending_irq);
362 memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap));
363 if (pending_irq >= 0) {
364 env->interrupt_bitmap[pending_irq / 64] |=
365 (uint64_t)1 << (pending_irq % 64);
367 qemu_get_be32s(f, &env->mp_state);
368 qemu_get_be64s(f, &env->tsc);
371 if (version_id >= 10) {
372 qemu_get_be64s(f, &env->mcg_cap);
373 if (env->mcg_cap && !kvm_enabled()) {
374 qemu_get_be64s(f, &env->mcg_status);
375 qemu_get_be64s(f, &env->mcg_ctl);
376 for (i = 0; i < (env->mcg_cap & 0xff); i++) {
377 qemu_get_be64s(f, &env->mce_banks[4*i]);
378 qemu_get_be64s(f, &env->mce_banks[4*i + 1]);
379 qemu_get_be64s(f, &env->mce_banks[4*i + 2]);
380 qemu_get_be64s(f, &env->mce_banks[4*i + 3]);
385 /* XXX: ensure compatiblity for halted bit ? */
386 /* XXX: compute redundant hflags bits */
387 env->hflags = hflags;
388 tlb_flush(env, 1);
389 cpu_synchronize_state(env, 1);
390 if (kvm_enabled()) {
391 /* when in-kernel irqchip is used, env->halted causes deadlock
392 because no userspace IRQs will ever clear this flag */
393 env->halted = 0;
394 if (version_id < 9) {
395 for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
396 qemu_get_be64s(f, &env->interrupt_bitmap[i]);
398 qemu_get_be64s(f, &env->tsc);
399 kvm_load_registers(env);
400 kvm_load_tsc(env);
401 if (version_id >= 5) {
402 qemu_get_be32s(f, &env->mp_state);
403 kvm_arch_load_mpstate(env);
405 } else {
406 kvm_load_registers(env);
407 kvm_load_tsc(env);
408 kvm_arch_load_mpstate(env);
412 if (version_id >= 11) {
413 qemu_get_be64s(f, &env->system_time_msr);
414 qemu_get_be64s(f, &env->wall_clock_msr);
416 return 0;