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