target-i386/machine.c: Convert to VMStateDescription. Change-Id: I6b61c70bc32e3e56e8bf62c8c00ab674f4a6de94
diff --git a/include/hw/hw.h b/include/hw/hw.h index 1bb8dee..9195dbc 100644 --- a/include/hw/hw.h +++ b/include/hw/hw.h
@@ -49,4 +49,29 @@ typedef int QEMUBootSetHandler(void *opaque, const char *boot_device); void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque); +#ifdef NEED_CPU_H +#if TARGET_LONG_BITS == 64 +#define VMSTATE_UINTTL_V(_f, _s, _v) \ + VMSTATE_UINT64_V(_f, _s, _v) +#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v) \ + VMSTATE_UINT64_EQUAL_V(_f, _s, _v) +#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \ + VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v) +#else +#define VMSTATE_UINTTL_V(_f, _s, _v) \ + VMSTATE_UINT32_V(_f, _s, _v) +#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v) \ + VMSTATE_UINT32_EQUAL_V(_f, _s, _v) +#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \ + VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v) +#endif +#define VMSTATE_UINTTL(_f, _s) \ + VMSTATE_UINTTL_V(_f, _s, 0) +#define VMSTATE_UINTTL_EQUAL(_f, _s) \ + VMSTATE_UINTTL_EQUAL_V(_f, _s, 0) +#define VMSTATE_UINTTL_ARRAY(_f, _s, _n) \ + VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0) + +#endif + #endif
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index ca588ce..1727583 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h
@@ -21,6 +21,7 @@ #include "config.h" #include "qemu-common.h" +#include "migration/vmstate.h" #ifdef TARGET_X86_64 #define TARGET_LONG_BITS 64 @@ -867,10 +868,7 @@ /* MTRRs */ uint64_t mtrr_fixed[11]; uint64_t mtrr_deftype; - struct { - uint64_t base; - uint64_t mask; - } mtrr_var[8]; + MTRRVar mtrr_var[8]; /* For KVM */ uint64_t interrupt_bitmap[256 / 64]; @@ -887,6 +885,9 @@ /* vmstate */ uint16_t fpus_vmstate; + uint16_t fptag_vmstate; + uint16_t fpregs_format_vmstate; + } CPUX86State; #include "cpu-qom.h" @@ -1054,8 +1055,6 @@ #define cpu_signal_handler cpu_x86_signal_handler #define cpu_list x86_cpu_list -#define CPU_SAVE_VERSION 10 - /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel #define MMU_MODE1_SUFFIX _user @@ -1209,4 +1208,8 @@ // Nothing to do on this architecture. } +extern const VMStateDescription vmstate_cpu_x86; + +#define vmstate_arch_cpu vmstate_cpu_x86 + #endif /* CPU_I386_H */
diff --git a/target-i386/machine.c b/target-i386/machine.c index 1829765..6f40a81 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c
@@ -6,301 +6,290 @@ #include "cpu.h" #include "sysemu/kvm.h" -static void cpu_put_seg(QEMUFile *f, SegmentCache *dt) -{ - qemu_put_be32(f, dt->selector); - qemu_put_betl(f, dt->base); - qemu_put_be32(f, dt->limit); - qemu_put_be32(f, dt->flags); +static const VMStateDescription vmstate_segment = { + .name = "segment", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT32(selector, SegmentCache), + VMSTATE_UINTTL(base, SegmentCache), + VMSTATE_UINT32(limit, SegmentCache), + VMSTATE_UINT32(flags, SegmentCache), + VMSTATE_END_OF_LIST() + } +}; + +#define VMSTATE_SEGMENT(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(SegmentCache), \ + .vmsd = &vmstate_segment, \ + .flags = VMS_STRUCT, \ + .offset = offsetof(_state, _field) \ + + type_check(SegmentCache,typeof_field(_state, _field)) \ } -static void cpu_get_seg(QEMUFile *f, SegmentCache *dt) -{ - dt->selector = qemu_get_be32(f); - dt->base = qemu_get_betl(f); - dt->limit = qemu_get_be32(f); - dt->flags = qemu_get_be32(f); -} +#define VMSTATE_SEGMENT_ARRAY(_field, _state, _n) \ + VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_segment, SegmentCache) -void cpu_save(QEMUFile *f, void *opaque) +static const VMStateDescription vmstate_xmm_reg = { + .name = "xmm_reg", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(XMM_Q(0), XMMReg), + VMSTATE_UINT64(XMM_Q(1), XMMReg), + VMSTATE_END_OF_LIST() + } +}; + +#define VMSTATE_XMM_REGS(_field, _state, _n) \ + VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_xmm_reg, XMMReg) + +static const VMStateDescription vmstate_mtrr_var = { + .name = "mtrr_var", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(base, MTRRVar), + VMSTATE_UINT64(mask, MTRRVar), + VMSTATE_END_OF_LIST() + } +}; + +#define VMSTATE_MTRR_VARS(_field, _state, _n) \ + VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_mtrr_var, MTRRVar) + +static int get_fpregs(QEMUFile *f, void *opaque, size_t size) { - CPUX86State *env = opaque; - uint16_t fptag, fpregs_format; - uint32_t hflags; + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; int i; - cpu_synchronize_state(ENV_GET_CPU(env), 0); + for (i = 0; i < 8; ++i) { + uint64_t mant; + qemu_get_be64s(f, &mant); + env->fpregs[i].mmx.MMX_Q(0) = mant; + } - for(i = 0; i < CPU_NB_REGS; i++) - qemu_put_betls(f, &env->regs[i]); - qemu_put_betls(f, &env->eip); - qemu_put_betls(f, &env->eflags); - hflags = env->hflags; /* XXX: suppress most of the redundant hflags */ - qemu_put_be32s(f, &hflags); + return 0; +} + +static void put_fpregs(QEMUFile *f, void *opaque, size_t size) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + int i; + + for (i = 0; i < 8; ++i) { + qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0)); + } +} + +static const VMStateInfo vmstate_fpregs = { + .name = "fpregs", + .get = get_fpregs, + .put = put_fpregs, +}; + +#define VMSTATE_FPREGS(_field, _state) \ + { \ + .name = "cpu/fpregs", \ + .version_id = 1, \ + .info = &vmstate_fpregs, \ + } + +static void put_mce_banks(QEMUFile *f, void *opaque, size_t size) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + int i; + + for (i = 0; i < (env->mcg_cap & 0xff); i++) { + qemu_put_be64s(f, &env->mce_banks[4*i]); + qemu_put_be64s(f, &env->mce_banks[4*i + 1]); + qemu_put_be64s(f, &env->mce_banks[4*i + 2]); + qemu_put_be64s(f, &env->mce_banks[4*i + 3]); + } +} + +static int get_mce_banks(QEMUFile *f, void *opaque, size_t size) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + int i; + + for (i = 0; i < (env->mcg_cap & 0xff); i++) { + qemu_get_be64s(f, &env->mce_banks[4*i]); + qemu_get_be64s(f, &env->mce_banks[4*i + 1]); + qemu_get_be64s(f, &env->mce_banks[4*i + 2]); + qemu_get_be64s(f, &env->mce_banks[4*i + 3]); + } + + return 0; +} + +static const VMStateInfo vmstate_mce_banks = { + .name = "mce_banks", + .get = get_mce_banks, + .put = put_mce_banks, +}; + +static const VMStateDescription vmstate_mcg_cap = { + .name = "cpu/mcg_cap", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(env.mcg_status, X86CPU), + VMSTATE_UINT64(env.mcg_ctl, X86CPU), + { + .name = "mce_banks", + .version_id = 1, + .info = &vmstate_mce_banks, + }, + VMSTATE_END_OF_LIST() + } +}; + +static bool mce_banks_exists(void *opaque, int version_id) +{ + X86CPU *cpu = opaque; + CPUX86State *env = &cpu->env; + + return (env->mcg_cap != 0); +} + +#define VMSTATE_MCG_CAP(_field, _state) \ + { \ + .name = "cpu/mcg_cap", \ + .offset = 0, \ + .flags = VMS_SINGLE, \ + .vmsd = &vmstate_mcg_cap, \ + .field_exists = mce_banks_exists, \ + } + +static void cpu_pre_save(void *opaque) +{ + X86CPU* cpu = opaque; + CPUX86State *env = &cpu->env; + int i; /* FPU */ env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; - fptag = 0; - for(i = 0; i < 8; i++) { - fptag |= ((!env->fptags[i]) << i); + env->fptag_vmstate = 0; + for (i = 0; i < 8; ++i) { + env->fptag_vmstate |= ((!env->fptags[i]) << i); } - qemu_put_be16s(f, &env->fpuc); - qemu_put_be16s(f, &env->fpus_vmstate); - qemu_put_be16s(f, &fptag); - - fpregs_format = 1; - qemu_put_be16s(f, &fpregs_format); - - for(i = 0; i < 8; i++) { - /* if we use doubles for float emulation, we save the doubles to - avoid losing information in case of MMX usage. It can give - problems if the image is restored on a CPU where long - doubles are used instead. */ - qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0)); - } - - for(i = 0; i < 6; i++) - cpu_put_seg(f, &env->segs[i]); - cpu_put_seg(f, &env->ldt); - cpu_put_seg(f, &env->tr); - cpu_put_seg(f, &env->gdt); - cpu_put_seg(f, &env->idt); - - qemu_put_be32s(f, &env->sysenter_cs); - qemu_put_betls(f, &env->sysenter_esp); - qemu_put_betls(f, &env->sysenter_eip); - - qemu_put_betls(f, &env->cr[0]); - qemu_put_betls(f, &env->cr[2]); - qemu_put_betls(f, &env->cr[3]); - qemu_put_betls(f, &env->cr[4]); - - for(i = 0; i < 8; i++) - qemu_put_betls(f, &env->dr[i]); - - /* MMU */ - qemu_put_sbe32s(f, &env->a20_mask); - - /* XMM */ - qemu_put_be32s(f, &env->mxcsr); - for(i = 0; i < CPU_NB_REGS; i++) { - qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0)); - qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1)); - } - -#ifdef TARGET_X86_64 - qemu_put_be64s(f, &env->efer); - qemu_put_be64s(f, &env->star); - qemu_put_be64s(f, &env->lstar); - qemu_put_be64s(f, &env->cstar); - qemu_put_be64s(f, &env->fmask); - qemu_put_be64s(f, &env->kernelgsbase); -#endif - qemu_put_be32s(f, &env->smbase); - - qemu_put_be64s(f, &env->pat); - qemu_put_be32s(f, &env->hflags2); - - qemu_put_be64s(f, &env->vm_hsave); - qemu_put_be64s(f, &env->vm_vmcb); - qemu_put_be64s(f, &env->tsc_offset); - qemu_put_be64s(f, &env->intercept); - qemu_put_be16s(f, &env->intercept_cr_read); - qemu_put_be16s(f, &env->intercept_cr_write); - qemu_put_be16s(f, &env->intercept_dr_read); - qemu_put_be16s(f, &env->intercept_dr_write); - qemu_put_be32s(f, &env->intercept_exceptions); - qemu_put_8s(f, &env->v_tpr); - - /* MTRRs */ - for(i = 0; i < 11; i++) - qemu_put_be64s(f, &env->mtrr_fixed[i]); - qemu_put_be64s(f, &env->mtrr_deftype); - for(i = 0; i < 8; i++) { - qemu_put_be64s(f, &env->mtrr_var[i].base); - qemu_put_be64s(f, &env->mtrr_var[i].mask); - } - - for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { - qemu_put_be64s(f, &env->interrupt_bitmap[i]); - } - qemu_put_be64s(f, &env->tsc); - qemu_put_be32s(f, &env->mp_state); - - /* MCE */ - qemu_put_be64s(f, &env->mcg_cap); - if (env->mcg_cap) { - qemu_put_be64s(f, &env->mcg_status); - qemu_put_be64s(f, &env->mcg_ctl); - for (i = 0; i < (env->mcg_cap & 0xff); i++) { - qemu_put_be64s(f, &env->mce_banks[4*i]); - qemu_put_be64s(f, &env->mce_banks[4*i + 1]); - qemu_put_be64s(f, &env->mce_banks[4*i + 2]); - qemu_put_be64s(f, &env->mce_banks[4*i + 3]); - } - } + env->fpregs_format_vmstate = 1; } -int cpu_load(QEMUFile *f, void *opaque, int version_id) +static int cpu_post_load(void *opaque, int version_id) { - CPUX86State *env = opaque; - CPUState *cs = ENV_GET_CPU(env); - int i, guess_mmx; - uint32_t hflags; - uint16_t fptag, fpregs_format; - - if (version_id < 3 || version_id > CPU_SAVE_VERSION) - return -EINVAL; - for(i = 0; i < CPU_NB_REGS; i++) - qemu_get_betls(f, &env->regs[i]); - qemu_get_betls(f, &env->eip); - qemu_get_betls(f, &env->eflags); - qemu_get_be32s(f, &hflags); - - qemu_get_be16s(f, &env->fpuc); - qemu_get_be16s(f, &env->fpus_vmstate); - qemu_get_be16s(f, &fptag); - qemu_get_be16s(f, &fpregs_format); - - /* NOTE: we cannot always restore the FPU state if the image come - from a host with a different 'USE_X86LDOUBLE' define. We guess - if we are in an MMX state to restore correctly in that case. */ - guess_mmx = ((fptag == 0xff) && (env->fpus_vmstate & 0x3800) == 0); - for(i = 0; i < 8; i++) { - uint64_t mant; - uint16_t exp; - - switch(fpregs_format) { - case 0: - mant = qemu_get_be64(f); - exp = qemu_get_be16(f); - /* difficult case */ - if (guess_mmx) - env->fpregs[i].mmx.MMX_Q(0) = mant; - else - env->fpregs[i].d = cpu_set_fp80(mant, exp); - break; - case 1: - mant = qemu_get_be64(f); - env->fpregs[i].mmx.MMX_Q(0) = mant; - break; - default: - return -EINVAL; - } - } + X86CPU *cpu = opaque; + CPUState *cs = CPU(cpu); + CPUX86State *env = &cpu->env; + int i; /* XXX: restore FPU round state */ env->fpstt = (env->fpus_vmstate >> 11) & 7; env->fpus = env->fpus_vmstate & ~0x3800; - fptag ^= 0xff; + env->fptag_vmstate ^= 0xff; for(i = 0; i < 8; i++) { - env->fptags[i] = (fptag >> i) & 1; + env->fptags[i] = (env->fptag_vmstate >> i) & 1; } - for(i = 0; i < 6; i++) - cpu_get_seg(f, &env->segs[i]); - cpu_get_seg(f, &env->ldt); - cpu_get_seg(f, &env->tr); - cpu_get_seg(f, &env->gdt); - cpu_get_seg(f, &env->idt); - - qemu_get_be32s(f, &env->sysenter_cs); - if (version_id >= 7) { - qemu_get_betls(f, &env->sysenter_esp); - qemu_get_betls(f, &env->sysenter_eip); - } else { - env->sysenter_esp = qemu_get_be32(f); - env->sysenter_eip = qemu_get_be32(f); - } - - qemu_get_betls(f, &env->cr[0]); - qemu_get_betls(f, &env->cr[2]); - qemu_get_betls(f, &env->cr[3]); - qemu_get_betls(f, &env->cr[4]); - - for(i = 0; i < 8; i++) - qemu_get_betls(f, &env->dr[i]); cpu_breakpoint_remove_all(cs, BP_CPU); cpu_watchpoint_remove_all(cs, BP_CPU); - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { hw_breakpoint_insert(env, i); - - /* MMU */ - qemu_get_sbe32s(f, &env->a20_mask); - - qemu_get_be32s(f, &env->mxcsr); - for(i = 0; i < CPU_NB_REGS; i++) { - qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0)); - qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1)); } - -#ifdef TARGET_X86_64 - qemu_get_be64s(f, &env->efer); - qemu_get_be64s(f, &env->star); - qemu_get_be64s(f, &env->lstar); - qemu_get_be64s(f, &env->cstar); - qemu_get_be64s(f, &env->fmask); - qemu_get_be64s(f, &env->kernelgsbase); -#endif - if (version_id >= 4) { - qemu_get_be32s(f, &env->smbase); - } - if (version_id >= 5) { - qemu_get_be64s(f, &env->pat); - qemu_get_be32s(f, &env->hflags2); - if (version_id < 6) - qemu_get_be32s(f, &ENV_GET_CPU(env)->halted); - - qemu_get_be64s(f, &env->vm_hsave); - qemu_get_be64s(f, &env->vm_vmcb); - qemu_get_be64s(f, &env->tsc_offset); - qemu_get_be64s(f, &env->intercept); - qemu_get_be16s(f, &env->intercept_cr_read); - qemu_get_be16s(f, &env->intercept_cr_write); - qemu_get_be16s(f, &env->intercept_dr_read); - qemu_get_be16s(f, &env->intercept_dr_write); - qemu_get_be32s(f, &env->intercept_exceptions); - qemu_get_8s(f, &env->v_tpr); - } - - if (version_id >= 8) { - /* MTRRs */ - for(i = 0; i < 11; i++) - qemu_get_be64s(f, &env->mtrr_fixed[i]); - qemu_get_be64s(f, &env->mtrr_deftype); - for(i = 0; i < 8; i++) { - qemu_get_be64s(f, &env->mtrr_var[i].base); - qemu_get_be64s(f, &env->mtrr_var[i].mask); - } - } - if (version_id >= 9) { - for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { - qemu_get_be64s(f, &env->interrupt_bitmap[i]); - } - qemu_get_be64s(f, &env->tsc); - qemu_get_be32s(f, &env->mp_state); - } - - if (version_id >= 10) { - qemu_get_be64s(f, &env->mcg_cap); - if (env->mcg_cap) { - qemu_get_be64s(f, &env->mcg_status); - qemu_get_be64s(f, &env->mcg_ctl); - for (i = 0; i < (env->mcg_cap & 0xff); i++) { - qemu_get_be64s(f, &env->mce_banks[4*i]); - qemu_get_be64s(f, &env->mce_banks[4*i + 1]); - qemu_get_be64s(f, &env->mce_banks[4*i + 2]); - qemu_get_be64s(f, &env->mce_banks[4*i + 3]); - } - } - } - - - /* XXX: ensure compatiblity for halted bit ? */ - /* XXX: compute redundant hflags bits */ - env->hflags = hflags; tlb_flush(cs, 1); - cpu_synchronize_state(ENV_GET_CPU(env), 1); + return 0; } + +const VMStateDescription vmstate_cpu_x86 = { + .name = "cpu", + .version_id = 11, + .minimum_version_id = 11, + .minimum_version_id_old = 11, + .pre_save = cpu_pre_save, + .post_load = cpu_post_load, + .fields = (VMStateField []) { + VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS), + VMSTATE_UINTTL(env.eip, X86CPU), + VMSTATE_UINTTL(env.eflags, X86CPU), + VMSTATE_UINT32(env.hflags, X86CPU), + /* FPU */ + VMSTATE_UINT16(env.fpuc, X86CPU), + VMSTATE_UINT16(env.fpus_vmstate, X86CPU), + VMSTATE_UINT16(env.fptag_vmstate, X86CPU), + VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU), + VMSTATE_FPREGS(env, X86CPU), + + VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6), + VMSTATE_SEGMENT(env.ldt, X86CPU), + VMSTATE_SEGMENT(env.tr, X86CPU), + VMSTATE_SEGMENT(env.gdt, X86CPU), + VMSTATE_SEGMENT(env.idt, X86CPU), + + VMSTATE_UINT32(env.sysenter_cs, X86CPU), + VMSTATE_UINTTL(env.sysenter_esp, X86CPU), + VMSTATE_UINTTL(env.sysenter_eip, X86CPU), + + VMSTATE_UINTTL(env.cr[0], X86CPU), + VMSTATE_UINTTL(env.cr[2], X86CPU), + VMSTATE_UINTTL(env.cr[3], X86CPU), + VMSTATE_UINTTL(env.cr[4], X86CPU), + + VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8), + + /* MMU */ + VMSTATE_INT32(env.a20_mask, X86CPU), + + /* XMM */ + VMSTATE_UINT32(env.mxcsr, X86CPU), + VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, CPU_NB_REGS), + + VMSTATE_UINT64(env.efer, X86CPU), + VMSTATE_UINT64(env.star, X86CPU), +#ifdef TARGET_X86_64 + VMSTATE_UINT64(env.lstar, X86CPU), + VMSTATE_UINT64(env.cstar, X86CPU), + VMSTATE_UINT64(env.fmask, X86CPU), + VMSTATE_UINT64(env.kernelgsbase, X86CPU), +#endif + VMSTATE_UINT32(env.smbase, X86CPU), + + VMSTATE_UINT64(env.pat, X86CPU), + VMSTATE_UINT32(env.hflags2, X86CPU), + + VMSTATE_UINT64(env.vm_hsave, X86CPU), + VMSTATE_UINT64(env.vm_vmcb, X86CPU), + VMSTATE_UINT64(env.tsc_offset, X86CPU), + VMSTATE_UINT64(env.intercept, X86CPU), + VMSTATE_UINT16(env.intercept_cr_read, X86CPU), + VMSTATE_UINT16(env.intercept_cr_write, X86CPU), + VMSTATE_UINT16(env.intercept_dr_read, X86CPU), + VMSTATE_UINT16(env.intercept_dr_write, X86CPU), + VMSTATE_UINT32(env.intercept_exceptions, X86CPU), + VMSTATE_UINT8(env.v_tpr, X86CPU), + + /* MTRRs */ + VMSTATE_UINT64_ARRAY(env.mtrr_fixed, X86CPU, 11), + VMSTATE_UINT64(env.mtrr_deftype, X86CPU), + VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, 8), + VMSTATE_UINT64_ARRAY(env.interrupt_bitmap, X86CPU, 256 / 64), + VMSTATE_UINT64(env.tsc, X86CPU), + VMSTATE_UINT32(env.mp_state, X86CPU), + + /* MCE */ + VMSTATE_UINT64(env.mcg_cap, X86CPU), + VMSTATE_MCG_CAP(env, X86CPU), + VMSTATE_END_OF_LIST() + }, +};