]> git.proxmox.com Git - mirror_qemu.git/blob - target-i386/machine.c
bdff44778617cdf35a28bae36dce502909402711
[mirror_qemu.git] / target-i386 / machine.c
1 #include "hw/hw.h"
2 #include "hw/boards.h"
3 #include "hw/i386/pc.h"
4 #include "hw/isa/isa.h"
5
6 #include "cpu.h"
7 #include "sysemu/kvm.h"
8
9 static const VMStateDescription vmstate_segment = {
10 .name = "segment",
11 .version_id = 1,
12 .minimum_version_id = 1,
13 .minimum_version_id_old = 1,
14 .fields = (VMStateField []) {
15 VMSTATE_UINT32(selector, SegmentCache),
16 VMSTATE_UINTTL(base, SegmentCache),
17 VMSTATE_UINT32(limit, SegmentCache),
18 VMSTATE_UINT32(flags, SegmentCache),
19 VMSTATE_END_OF_LIST()
20 }
21 };
22
23 #define VMSTATE_SEGMENT(_field, _state) { \
24 .name = (stringify(_field)), \
25 .size = sizeof(SegmentCache), \
26 .vmsd = &vmstate_segment, \
27 .flags = VMS_STRUCT, \
28 .offset = offsetof(_state, _field) \
29 + type_check(SegmentCache,typeof_field(_state, _field)) \
30 }
31
32 #define VMSTATE_SEGMENT_ARRAY(_field, _state, _n) \
33 VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_segment, SegmentCache)
34
35 static const VMStateDescription vmstate_xmm_reg = {
36 .name = "xmm_reg",
37 .version_id = 1,
38 .minimum_version_id = 1,
39 .minimum_version_id_old = 1,
40 .fields = (VMStateField []) {
41 VMSTATE_UINT64(XMM_Q(0), XMMReg),
42 VMSTATE_UINT64(XMM_Q(1), XMMReg),
43 VMSTATE_END_OF_LIST()
44 }
45 };
46
47 #define VMSTATE_XMM_REGS(_field, _state, _n) \
48 VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_xmm_reg, XMMReg)
49
50 /* YMMH format is the same as XMM */
51 static const VMStateDescription vmstate_ymmh_reg = {
52 .name = "ymmh_reg",
53 .version_id = 1,
54 .minimum_version_id = 1,
55 .minimum_version_id_old = 1,
56 .fields = (VMStateField []) {
57 VMSTATE_UINT64(XMM_Q(0), XMMReg),
58 VMSTATE_UINT64(XMM_Q(1), XMMReg),
59 VMSTATE_END_OF_LIST()
60 }
61 };
62
63 #define VMSTATE_YMMH_REGS_VARS(_field, _state, _n, _v) \
64 VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_ymmh_reg, XMMReg)
65
66 static const VMStateDescription vmstate_bnd_regs = {
67 .name = "bnd_regs",
68 .version_id = 1,
69 .minimum_version_id = 1,
70 .minimum_version_id_old = 1,
71 .fields = (VMStateField[]) {
72 VMSTATE_UINT64(lb, BNDReg),
73 VMSTATE_UINT64(ub, BNDReg),
74 VMSTATE_END_OF_LIST()
75 }
76 };
77
78 #define VMSTATE_BND_REGS(_field, _state, _n) \
79 VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_bnd_regs, BNDReg)
80
81 static const VMStateDescription vmstate_mtrr_var = {
82 .name = "mtrr_var",
83 .version_id = 1,
84 .minimum_version_id = 1,
85 .minimum_version_id_old = 1,
86 .fields = (VMStateField []) {
87 VMSTATE_UINT64(base, MTRRVar),
88 VMSTATE_UINT64(mask, MTRRVar),
89 VMSTATE_END_OF_LIST()
90 }
91 };
92
93 #define VMSTATE_MTRR_VARS(_field, _state, _n, _v) \
94 VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar)
95
96 static void put_fpreg_error(QEMUFile *f, void *opaque, size_t size)
97 {
98 fprintf(stderr, "call put_fpreg() with invalid arguments\n");
99 exit(0);
100 }
101
102 /* XXX: add that in a FPU generic layer */
103 union x86_longdouble {
104 uint64_t mant;
105 uint16_t exp;
106 };
107
108 #define MANTD1(fp) (fp & ((1LL << 52) - 1))
109 #define EXPBIAS1 1023
110 #define EXPD1(fp) ((fp >> 52) & 0x7FF)
111 #define SIGND1(fp) ((fp >> 32) & 0x80000000)
112
113 static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
114 {
115 int e;
116 /* mantissa */
117 p->mant = (MANTD1(temp) << 11) | (1LL << 63);
118 /* exponent + sign */
119 e = EXPD1(temp) - EXPBIAS1 + 16383;
120 e |= SIGND1(temp) >> 16;
121 p->exp = e;
122 }
123
124 static int get_fpreg(QEMUFile *f, void *opaque, size_t size)
125 {
126 FPReg *fp_reg = opaque;
127 uint64_t mant;
128 uint16_t exp;
129
130 qemu_get_be64s(f, &mant);
131 qemu_get_be16s(f, &exp);
132 fp_reg->d = cpu_set_fp80(mant, exp);
133 return 0;
134 }
135
136 static void put_fpreg(QEMUFile *f, void *opaque, size_t size)
137 {
138 FPReg *fp_reg = opaque;
139 uint64_t mant;
140 uint16_t exp;
141 /* we save the real CPU data (in case of MMX usage only 'mant'
142 contains the MMX register */
143 cpu_get_fp80(&mant, &exp, fp_reg->d);
144 qemu_put_be64s(f, &mant);
145 qemu_put_be16s(f, &exp);
146 }
147
148 static const VMStateInfo vmstate_fpreg = {
149 .name = "fpreg",
150 .get = get_fpreg,
151 .put = put_fpreg,
152 };
153
154 static int get_fpreg_1_mmx(QEMUFile *f, void *opaque, size_t size)
155 {
156 union x86_longdouble *p = opaque;
157 uint64_t mant;
158
159 qemu_get_be64s(f, &mant);
160 p->mant = mant;
161 p->exp = 0xffff;
162 return 0;
163 }
164
165 static const VMStateInfo vmstate_fpreg_1_mmx = {
166 .name = "fpreg_1_mmx",
167 .get = get_fpreg_1_mmx,
168 .put = put_fpreg_error,
169 };
170
171 static int get_fpreg_1_no_mmx(QEMUFile *f, void *opaque, size_t size)
172 {
173 union x86_longdouble *p = opaque;
174 uint64_t mant;
175
176 qemu_get_be64s(f, &mant);
177 fp64_to_fp80(p, mant);
178 return 0;
179 }
180
181 static const VMStateInfo vmstate_fpreg_1_no_mmx = {
182 .name = "fpreg_1_no_mmx",
183 .get = get_fpreg_1_no_mmx,
184 .put = put_fpreg_error,
185 };
186
187 static bool fpregs_is_0(void *opaque, int version_id)
188 {
189 X86CPU *cpu = opaque;
190 CPUX86State *env = &cpu->env;
191
192 return (env->fpregs_format_vmstate == 0);
193 }
194
195 static bool fpregs_is_1_mmx(void *opaque, int version_id)
196 {
197 X86CPU *cpu = opaque;
198 CPUX86State *env = &cpu->env;
199 int guess_mmx;
200
201 guess_mmx = ((env->fptag_vmstate == 0xff) &&
202 (env->fpus_vmstate & 0x3800) == 0);
203 return (guess_mmx && (env->fpregs_format_vmstate == 1));
204 }
205
206 static bool fpregs_is_1_no_mmx(void *opaque, int version_id)
207 {
208 X86CPU *cpu = opaque;
209 CPUX86State *env = &cpu->env;
210 int guess_mmx;
211
212 guess_mmx = ((env->fptag_vmstate == 0xff) &&
213 (env->fpus_vmstate & 0x3800) == 0);
214 return (!guess_mmx && (env->fpregs_format_vmstate == 1));
215 }
216
217 #define VMSTATE_FP_REGS(_field, _state, _n) \
218 VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_0, vmstate_fpreg, FPReg), \
219 VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_mmx, vmstate_fpreg_1_mmx, FPReg), \
220 VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_no_mmx, vmstate_fpreg_1_no_mmx, FPReg)
221
222 static bool version_is_5(void *opaque, int version_id)
223 {
224 return version_id == 5;
225 }
226
227 #ifdef TARGET_X86_64
228 static bool less_than_7(void *opaque, int version_id)
229 {
230 return version_id < 7;
231 }
232
233 static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
234 {
235 uint64_t *v = pv;
236 *v = qemu_get_be32(f);
237 return 0;
238 }
239
240 static void put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
241 {
242 uint64_t *v = pv;
243 qemu_put_be32(f, *v);
244 }
245
246 static const VMStateInfo vmstate_hack_uint64_as_uint32 = {
247 .name = "uint64_as_uint32",
248 .get = get_uint64_as_uint32,
249 .put = put_uint64_as_uint32,
250 };
251
252 #define VMSTATE_HACK_UINT32(_f, _s, _t) \
253 VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint64_as_uint32, uint64_t)
254 #endif
255
256 static void cpu_pre_save(void *opaque)
257 {
258 X86CPU *cpu = opaque;
259 CPUX86State *env = &cpu->env;
260 int i;
261
262 /* FPU */
263 env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
264 env->fptag_vmstate = 0;
265 for(i = 0; i < 8; i++) {
266 env->fptag_vmstate |= ((!env->fptags[i]) << i);
267 }
268
269 env->fpregs_format_vmstate = 0;
270
271 /*
272 * Real mode guest segments register DPL should be zero.
273 * Older KVM version were setting it wrongly.
274 * Fixing it will allow live migration to host with unrestricted guest
275 * support (otherwise the migration will fail with invalid guest state
276 * error).
277 */
278 if (!(env->cr[0] & CR0_PE_MASK) &&
279 (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) {
280 env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK);
281 env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK);
282 env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK);
283 env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK);
284 env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK);
285 env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK);
286 }
287
288 }
289
290 static int cpu_post_load(void *opaque, int version_id)
291 {
292 X86CPU *cpu = opaque;
293 CPUState *cs = CPU(cpu);
294 CPUX86State *env = &cpu->env;
295 int i;
296
297 /*
298 * Real mode guest segments register DPL should be zero.
299 * Older KVM version were setting it wrongly.
300 * Fixing it will allow live migration from such host that don't have
301 * restricted guest support to a host with unrestricted guest support
302 * (otherwise the migration will fail with invalid guest state
303 * error).
304 */
305 if (!(env->cr[0] & CR0_PE_MASK) &&
306 (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) {
307 env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK);
308 env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK);
309 env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK);
310 env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK);
311 env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK);
312 env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK);
313 }
314
315 /* Older versions of QEMU incorrectly used CS.DPL as the CPL when
316 * running under KVM. This is wrong for conforming code segments.
317 * Luckily, in our implementation the CPL field of hflags is redundant
318 * and we can get the right value from the SS descriptor privilege level.
319 */
320 env->hflags &= ~HF_CPL_MASK;
321 env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;
322
323 /* XXX: restore FPU round state */
324 env->fpstt = (env->fpus_vmstate >> 11) & 7;
325 env->fpus = env->fpus_vmstate & ~0x3800;
326 env->fptag_vmstate ^= 0xff;
327 for(i = 0; i < 8; i++) {
328 env->fptags[i] = (env->fptag_vmstate >> i) & 1;
329 }
330
331 cpu_breakpoint_remove_all(cs, BP_CPU);
332 cpu_watchpoint_remove_all(cs, BP_CPU);
333 for (i = 0; i < DR7_MAX_BP; i++) {
334 hw_breakpoint_insert(env, i);
335 }
336 tlb_flush(cs, 1);
337
338 return 0;
339 }
340
341 static bool async_pf_msr_needed(void *opaque)
342 {
343 X86CPU *cpu = opaque;
344
345 return cpu->env.async_pf_en_msr != 0;
346 }
347
348 static bool pv_eoi_msr_needed(void *opaque)
349 {
350 X86CPU *cpu = opaque;
351
352 return cpu->env.pv_eoi_en_msr != 0;
353 }
354
355 static bool steal_time_msr_needed(void *opaque)
356 {
357 X86CPU *cpu = opaque;
358
359 return cpu->env.steal_time_msr != 0;
360 }
361
362 static const VMStateDescription vmstate_steal_time_msr = {
363 .name = "cpu/steal_time_msr",
364 .version_id = 1,
365 .minimum_version_id = 1,
366 .minimum_version_id_old = 1,
367 .fields = (VMStateField []) {
368 VMSTATE_UINT64(env.steal_time_msr, X86CPU),
369 VMSTATE_END_OF_LIST()
370 }
371 };
372
373 static const VMStateDescription vmstate_async_pf_msr = {
374 .name = "cpu/async_pf_msr",
375 .version_id = 1,
376 .minimum_version_id = 1,
377 .minimum_version_id_old = 1,
378 .fields = (VMStateField []) {
379 VMSTATE_UINT64(env.async_pf_en_msr, X86CPU),
380 VMSTATE_END_OF_LIST()
381 }
382 };
383
384 static const VMStateDescription vmstate_pv_eoi_msr = {
385 .name = "cpu/async_pv_eoi_msr",
386 .version_id = 1,
387 .minimum_version_id = 1,
388 .minimum_version_id_old = 1,
389 .fields = (VMStateField []) {
390 VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU),
391 VMSTATE_END_OF_LIST()
392 }
393 };
394
395 static bool fpop_ip_dp_needed(void *opaque)
396 {
397 X86CPU *cpu = opaque;
398 CPUX86State *env = &cpu->env;
399
400 return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0;
401 }
402
403 static const VMStateDescription vmstate_fpop_ip_dp = {
404 .name = "cpu/fpop_ip_dp",
405 .version_id = 1,
406 .minimum_version_id = 1,
407 .minimum_version_id_old = 1,
408 .fields = (VMStateField []) {
409 VMSTATE_UINT16(env.fpop, X86CPU),
410 VMSTATE_UINT64(env.fpip, X86CPU),
411 VMSTATE_UINT64(env.fpdp, X86CPU),
412 VMSTATE_END_OF_LIST()
413 }
414 };
415
416 static bool tsc_adjust_needed(void *opaque)
417 {
418 X86CPU *cpu = opaque;
419 CPUX86State *env = &cpu->env;
420
421 return env->tsc_adjust != 0;
422 }
423
424 static const VMStateDescription vmstate_msr_tsc_adjust = {
425 .name = "cpu/msr_tsc_adjust",
426 .version_id = 1,
427 .minimum_version_id = 1,
428 .minimum_version_id_old = 1,
429 .fields = (VMStateField[]) {
430 VMSTATE_UINT64(env.tsc_adjust, X86CPU),
431 VMSTATE_END_OF_LIST()
432 }
433 };
434
435 static bool tscdeadline_needed(void *opaque)
436 {
437 X86CPU *cpu = opaque;
438 CPUX86State *env = &cpu->env;
439
440 return env->tsc_deadline != 0;
441 }
442
443 static const VMStateDescription vmstate_msr_tscdeadline = {
444 .name = "cpu/msr_tscdeadline",
445 .version_id = 1,
446 .minimum_version_id = 1,
447 .minimum_version_id_old = 1,
448 .fields = (VMStateField []) {
449 VMSTATE_UINT64(env.tsc_deadline, X86CPU),
450 VMSTATE_END_OF_LIST()
451 }
452 };
453
454 static bool misc_enable_needed(void *opaque)
455 {
456 X86CPU *cpu = opaque;
457 CPUX86State *env = &cpu->env;
458
459 return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT;
460 }
461
462 static bool feature_control_needed(void *opaque)
463 {
464 X86CPU *cpu = opaque;
465 CPUX86State *env = &cpu->env;
466
467 return env->msr_ia32_feature_control != 0;
468 }
469
470 static const VMStateDescription vmstate_msr_ia32_misc_enable = {
471 .name = "cpu/msr_ia32_misc_enable",
472 .version_id = 1,
473 .minimum_version_id = 1,
474 .minimum_version_id_old = 1,
475 .fields = (VMStateField []) {
476 VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU),
477 VMSTATE_END_OF_LIST()
478 }
479 };
480
481 static const VMStateDescription vmstate_msr_ia32_feature_control = {
482 .name = "cpu/msr_ia32_feature_control",
483 .version_id = 1,
484 .minimum_version_id = 1,
485 .minimum_version_id_old = 1,
486 .fields = (VMStateField []) {
487 VMSTATE_UINT64(env.msr_ia32_feature_control, X86CPU),
488 VMSTATE_END_OF_LIST()
489 }
490 };
491
492 static bool pmu_enable_needed(void *opaque)
493 {
494 X86CPU *cpu = opaque;
495 CPUX86State *env = &cpu->env;
496 int i;
497
498 if (env->msr_fixed_ctr_ctrl || env->msr_global_ctrl ||
499 env->msr_global_status || env->msr_global_ovf_ctrl) {
500 return true;
501 }
502 for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
503 if (env->msr_fixed_counters[i]) {
504 return true;
505 }
506 }
507 for (i = 0; i < MAX_GP_COUNTERS; i++) {
508 if (env->msr_gp_counters[i] || env->msr_gp_evtsel[i]) {
509 return true;
510 }
511 }
512
513 return false;
514 }
515
516 static const VMStateDescription vmstate_msr_architectural_pmu = {
517 .name = "cpu/msr_architectural_pmu",
518 .version_id = 1,
519 .minimum_version_id = 1,
520 .minimum_version_id_old = 1,
521 .fields = (VMStateField []) {
522 VMSTATE_UINT64(env.msr_fixed_ctr_ctrl, X86CPU),
523 VMSTATE_UINT64(env.msr_global_ctrl, X86CPU),
524 VMSTATE_UINT64(env.msr_global_status, X86CPU),
525 VMSTATE_UINT64(env.msr_global_ovf_ctrl, X86CPU),
526 VMSTATE_UINT64_ARRAY(env.msr_fixed_counters, X86CPU, MAX_FIXED_COUNTERS),
527 VMSTATE_UINT64_ARRAY(env.msr_gp_counters, X86CPU, MAX_GP_COUNTERS),
528 VMSTATE_UINT64_ARRAY(env.msr_gp_evtsel, X86CPU, MAX_GP_COUNTERS),
529 VMSTATE_END_OF_LIST()
530 }
531 };
532
533 static bool mpx_needed(void *opaque)
534 {
535 X86CPU *cpu = opaque;
536 CPUX86State *env = &cpu->env;
537 unsigned int i;
538
539 for (i = 0; i < 4; i++) {
540 if (env->bnd_regs[i].lb || env->bnd_regs[i].ub) {
541 return true;
542 }
543 }
544
545 if (env->bndcs_regs.cfgu || env->bndcs_regs.sts) {
546 return true;
547 }
548
549 return !!env->msr_bndcfgs;
550 }
551
552 static const VMStateDescription vmstate_mpx = {
553 .name = "cpu/mpx",
554 .version_id = 1,
555 .minimum_version_id = 1,
556 .minimum_version_id_old = 1,
557 .fields = (VMStateField[]) {
558 VMSTATE_BND_REGS(env.bnd_regs, X86CPU, 4),
559 VMSTATE_UINT64(env.bndcs_regs.cfgu, X86CPU),
560 VMSTATE_UINT64(env.bndcs_regs.sts, X86CPU),
561 VMSTATE_UINT64(env.msr_bndcfgs, X86CPU),
562 VMSTATE_END_OF_LIST()
563 }
564 };
565
566 static bool hyperv_hypercall_enable_needed(void *opaque)
567 {
568 X86CPU *cpu = opaque;
569 CPUX86State *env = &cpu->env;
570
571 return env->msr_hv_hypercall != 0 || env->msr_hv_guest_os_id != 0;
572 }
573
574 static const VMStateDescription vmstate_msr_hypercall_hypercall = {
575 .name = "cpu/msr_hyperv_hypercall",
576 .version_id = 1,
577 .minimum_version_id = 1,
578 .minimum_version_id_old = 1,
579 .fields = (VMStateField []) {
580 VMSTATE_UINT64(env.msr_hv_guest_os_id, X86CPU),
581 VMSTATE_UINT64(env.msr_hv_hypercall, X86CPU),
582 VMSTATE_END_OF_LIST()
583 }
584 };
585
586 static bool hyperv_vapic_enable_needed(void *opaque)
587 {
588 X86CPU *cpu = opaque;
589 CPUX86State *env = &cpu->env;
590
591 return env->msr_hv_vapic != 0;
592 }
593
594 static const VMStateDescription vmstate_msr_hyperv_vapic = {
595 .name = "cpu/msr_hyperv_vapic",
596 .version_id = 1,
597 .minimum_version_id = 1,
598 .minimum_version_id_old = 1,
599 .fields = (VMStateField []) {
600 VMSTATE_UINT64(env.msr_hv_vapic, X86CPU),
601 VMSTATE_END_OF_LIST()
602 }
603 };
604
605 static bool hyperv_time_enable_needed(void *opaque)
606 {
607 X86CPU *cpu = opaque;
608 CPUX86State *env = &cpu->env;
609
610 return env->msr_hv_tsc != 0;
611 }
612
613 static const VMStateDescription vmstate_msr_hyperv_time = {
614 .name = "cpu/msr_hyperv_time",
615 .version_id = 1,
616 .minimum_version_id = 1,
617 .minimum_version_id_old = 1,
618 .fields = (VMStateField []) {
619 VMSTATE_UINT64(env.msr_hv_tsc, X86CPU),
620 VMSTATE_END_OF_LIST()
621 }
622 };
623
624 const VMStateDescription vmstate_x86_cpu = {
625 .name = "cpu",
626 .version_id = 12,
627 .minimum_version_id = 3,
628 .minimum_version_id_old = 3,
629 .pre_save = cpu_pre_save,
630 .post_load = cpu_post_load,
631 .fields = (VMStateField []) {
632 VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS),
633 VMSTATE_UINTTL(env.eip, X86CPU),
634 VMSTATE_UINTTL(env.eflags, X86CPU),
635 VMSTATE_UINT32(env.hflags, X86CPU),
636 /* FPU */
637 VMSTATE_UINT16(env.fpuc, X86CPU),
638 VMSTATE_UINT16(env.fpus_vmstate, X86CPU),
639 VMSTATE_UINT16(env.fptag_vmstate, X86CPU),
640 VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU),
641 VMSTATE_FP_REGS(env.fpregs, X86CPU, 8),
642
643 VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6),
644 VMSTATE_SEGMENT(env.ldt, X86CPU),
645 VMSTATE_SEGMENT(env.tr, X86CPU),
646 VMSTATE_SEGMENT(env.gdt, X86CPU),
647 VMSTATE_SEGMENT(env.idt, X86CPU),
648
649 VMSTATE_UINT32(env.sysenter_cs, X86CPU),
650 #ifdef TARGET_X86_64
651 /* Hack: In v7 size changed from 32 to 64 bits on x86_64 */
652 VMSTATE_HACK_UINT32(env.sysenter_esp, X86CPU, less_than_7),
653 VMSTATE_HACK_UINT32(env.sysenter_eip, X86CPU, less_than_7),
654 VMSTATE_UINTTL_V(env.sysenter_esp, X86CPU, 7),
655 VMSTATE_UINTTL_V(env.sysenter_eip, X86CPU, 7),
656 #else
657 VMSTATE_UINTTL(env.sysenter_esp, X86CPU),
658 VMSTATE_UINTTL(env.sysenter_eip, X86CPU),
659 #endif
660
661 VMSTATE_UINTTL(env.cr[0], X86CPU),
662 VMSTATE_UINTTL(env.cr[2], X86CPU),
663 VMSTATE_UINTTL(env.cr[3], X86CPU),
664 VMSTATE_UINTTL(env.cr[4], X86CPU),
665 VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8),
666 /* MMU */
667 VMSTATE_INT32(env.a20_mask, X86CPU),
668 /* XMM */
669 VMSTATE_UINT32(env.mxcsr, X86CPU),
670 VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, CPU_NB_REGS),
671
672 #ifdef TARGET_X86_64
673 VMSTATE_UINT64(env.efer, X86CPU),
674 VMSTATE_UINT64(env.star, X86CPU),
675 VMSTATE_UINT64(env.lstar, X86CPU),
676 VMSTATE_UINT64(env.cstar, X86CPU),
677 VMSTATE_UINT64(env.fmask, X86CPU),
678 VMSTATE_UINT64(env.kernelgsbase, X86CPU),
679 #endif
680 VMSTATE_UINT32_V(env.smbase, X86CPU, 4),
681
682 VMSTATE_UINT64_V(env.pat, X86CPU, 5),
683 VMSTATE_UINT32_V(env.hflags2, X86CPU, 5),
684
685 VMSTATE_UINT32_TEST(parent_obj.halted, X86CPU, version_is_5),
686 VMSTATE_UINT64_V(env.vm_hsave, X86CPU, 5),
687 VMSTATE_UINT64_V(env.vm_vmcb, X86CPU, 5),
688 VMSTATE_UINT64_V(env.tsc_offset, X86CPU, 5),
689 VMSTATE_UINT64_V(env.intercept, X86CPU, 5),
690 VMSTATE_UINT16_V(env.intercept_cr_read, X86CPU, 5),
691 VMSTATE_UINT16_V(env.intercept_cr_write, X86CPU, 5),
692 VMSTATE_UINT16_V(env.intercept_dr_read, X86CPU, 5),
693 VMSTATE_UINT16_V(env.intercept_dr_write, X86CPU, 5),
694 VMSTATE_UINT32_V(env.intercept_exceptions, X86CPU, 5),
695 VMSTATE_UINT8_V(env.v_tpr, X86CPU, 5),
696 /* MTRRs */
697 VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8),
698 VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8),
699 VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, 8, 8),
700 /* KVM-related states */
701 VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9),
702 VMSTATE_UINT32_V(env.mp_state, X86CPU, 9),
703 VMSTATE_UINT64_V(env.tsc, X86CPU, 9),
704 VMSTATE_INT32_V(env.exception_injected, X86CPU, 11),
705 VMSTATE_UINT8_V(env.soft_interrupt, X86CPU, 11),
706 VMSTATE_UINT8_V(env.nmi_injected, X86CPU, 11),
707 VMSTATE_UINT8_V(env.nmi_pending, X86CPU, 11),
708 VMSTATE_UINT8_V(env.has_error_code, X86CPU, 11),
709 VMSTATE_UINT32_V(env.sipi_vector, X86CPU, 11),
710 /* MCE */
711 VMSTATE_UINT64_V(env.mcg_cap, X86CPU, 10),
712 VMSTATE_UINT64_V(env.mcg_status, X86CPU, 10),
713 VMSTATE_UINT64_V(env.mcg_ctl, X86CPU, 10),
714 VMSTATE_UINT64_ARRAY_V(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4, 10),
715 /* rdtscp */
716 VMSTATE_UINT64_V(env.tsc_aux, X86CPU, 11),
717 /* KVM pvclock msr */
718 VMSTATE_UINT64_V(env.system_time_msr, X86CPU, 11),
719 VMSTATE_UINT64_V(env.wall_clock_msr, X86CPU, 11),
720 /* XSAVE related fields */
721 VMSTATE_UINT64_V(env.xcr0, X86CPU, 12),
722 VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12),
723 VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, CPU_NB_REGS, 12),
724 VMSTATE_END_OF_LIST()
725 /* The above list is not sorted /wrt version numbers, watch out! */
726 },
727 .subsections = (VMStateSubsection []) {
728 {
729 .vmsd = &vmstate_async_pf_msr,
730 .needed = async_pf_msr_needed,
731 } , {
732 .vmsd = &vmstate_pv_eoi_msr,
733 .needed = pv_eoi_msr_needed,
734 } , {
735 .vmsd = &vmstate_steal_time_msr,
736 .needed = steal_time_msr_needed,
737 } , {
738 .vmsd = &vmstate_fpop_ip_dp,
739 .needed = fpop_ip_dp_needed,
740 }, {
741 .vmsd = &vmstate_msr_tsc_adjust,
742 .needed = tsc_adjust_needed,
743 }, {
744 .vmsd = &vmstate_msr_tscdeadline,
745 .needed = tscdeadline_needed,
746 }, {
747 .vmsd = &vmstate_msr_ia32_misc_enable,
748 .needed = misc_enable_needed,
749 }, {
750 .vmsd = &vmstate_msr_ia32_feature_control,
751 .needed = feature_control_needed,
752 }, {
753 .vmsd = &vmstate_msr_architectural_pmu,
754 .needed = pmu_enable_needed,
755 } , {
756 .vmsd = &vmstate_mpx,
757 .needed = mpx_needed,
758 }, {
759 .vmsd = &vmstate_msr_hypercall_hypercall,
760 .needed = hyperv_hypercall_enable_needed,
761 }, {
762 .vmsd = &vmstate_msr_hyperv_vapic,
763 .needed = hyperv_vapic_enable_needed,
764 }, {
765 .vmsd = &vmstate_msr_hyperv_time,
766 .needed = hyperv_time_enable_needed,
767 } , {
768 /* empty */
769 }
770 }
771 };