1b6a0aa05SPeter Maydell #include "qemu/osdep.h" 233c11879SPaolo Bonzini #include "qemu-common.h" 333c11879SPaolo Bonzini #include "cpu.h" 463c91552SPaolo Bonzini #include "exec/exec-all.h" 58dd3dca3Saurel32 #include "hw/hw.h" 68dd3dca3Saurel32 #include "hw/boards.h" 70d09e41aSPaolo Bonzini #include "hw/i386/pc.h" 80d09e41aSPaolo Bonzini #include "hw/isa/isa.h" 91e00b8d5SPaolo Bonzini #include "migration/cpu.h" 108dd3dca3Saurel32 119c17d615SPaolo Bonzini #include "sysemu/kvm.h" 128dd3dca3Saurel32 1336f96c4bSHaozhong Zhang #include "qemu/error-report.h" 1436f96c4bSHaozhong Zhang 1566e6d55bSJuan Quintela static const VMStateDescription vmstate_segment = { 1666e6d55bSJuan Quintela .name = "segment", 1766e6d55bSJuan Quintela .version_id = 1, 1866e6d55bSJuan Quintela .minimum_version_id = 1, 1966e6d55bSJuan Quintela .fields = (VMStateField[]) { 2066e6d55bSJuan Quintela VMSTATE_UINT32(selector, SegmentCache), 2166e6d55bSJuan Quintela VMSTATE_UINTTL(base, SegmentCache), 2266e6d55bSJuan Quintela VMSTATE_UINT32(limit, SegmentCache), 2366e6d55bSJuan Quintela VMSTATE_UINT32(flags, SegmentCache), 2466e6d55bSJuan Quintela VMSTATE_END_OF_LIST() 2566e6d55bSJuan Quintela } 2666e6d55bSJuan Quintela }; 2766e6d55bSJuan Quintela 280cb892aaSJuan Quintela #define VMSTATE_SEGMENT(_field, _state) { \ 290cb892aaSJuan Quintela .name = (stringify(_field)), \ 300cb892aaSJuan Quintela .size = sizeof(SegmentCache), \ 310cb892aaSJuan Quintela .vmsd = &vmstate_segment, \ 320cb892aaSJuan Quintela .flags = VMS_STRUCT, \ 330cb892aaSJuan Quintela .offset = offsetof(_state, _field) \ 340cb892aaSJuan Quintela + type_check(SegmentCache,typeof_field(_state, _field)) \ 358dd3dca3Saurel32 } 368dd3dca3Saurel32 370cb892aaSJuan Quintela #define VMSTATE_SEGMENT_ARRAY(_field, _state, _n) \ 380cb892aaSJuan Quintela VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_segment, SegmentCache) 398dd3dca3Saurel32 40fc3b0aa2SJuan Quintela static const VMStateDescription vmstate_xmm_reg = { 41fc3b0aa2SJuan Quintela .name = "xmm_reg", 42fc3b0aa2SJuan Quintela .version_id = 1, 43fc3b0aa2SJuan Quintela .minimum_version_id = 1, 44fc3b0aa2SJuan Quintela .fields = (VMStateField[]) { 4519cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(0), ZMMReg), 4619cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(1), ZMMReg), 47fc3b0aa2SJuan Quintela VMSTATE_END_OF_LIST() 48fc3b0aa2SJuan Quintela } 49fc3b0aa2SJuan Quintela }; 50fc3b0aa2SJuan Quintela 51a03c3e90SPaolo Bonzini #define VMSTATE_XMM_REGS(_field, _state, _start) \ 52a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 53fa451874SEduardo Habkost vmstate_xmm_reg, ZMMReg) 54fc3b0aa2SJuan Quintela 55b7711471SPaolo Bonzini /* YMMH format is the same as XMM, but for bits 128-255 */ 56f1665b21SSheng Yang static const VMStateDescription vmstate_ymmh_reg = { 57f1665b21SSheng Yang .name = "ymmh_reg", 58f1665b21SSheng Yang .version_id = 1, 59f1665b21SSheng Yang .minimum_version_id = 1, 60f1665b21SSheng Yang .fields = (VMStateField[]) { 6119cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(2), ZMMReg), 6219cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(3), ZMMReg), 63f1665b21SSheng Yang VMSTATE_END_OF_LIST() 64f1665b21SSheng Yang } 65f1665b21SSheng Yang }; 66f1665b21SSheng Yang 67a03c3e90SPaolo Bonzini #define VMSTATE_YMMH_REGS_VARS(_field, _state, _start, _v) \ 68a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, _v, \ 69fa451874SEduardo Habkost vmstate_ymmh_reg, ZMMReg) 70f1665b21SSheng Yang 719aecd6f8SChao Peng static const VMStateDescription vmstate_zmmh_reg = { 729aecd6f8SChao Peng .name = "zmmh_reg", 739aecd6f8SChao Peng .version_id = 1, 749aecd6f8SChao Peng .minimum_version_id = 1, 759aecd6f8SChao Peng .fields = (VMStateField[]) { 7619cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(4), ZMMReg), 7719cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(5), ZMMReg), 7819cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(6), ZMMReg), 7919cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(7), ZMMReg), 809aecd6f8SChao Peng VMSTATE_END_OF_LIST() 819aecd6f8SChao Peng } 829aecd6f8SChao Peng }; 839aecd6f8SChao Peng 84a03c3e90SPaolo Bonzini #define VMSTATE_ZMMH_REGS_VARS(_field, _state, _start) \ 85a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 86fa451874SEduardo Habkost vmstate_zmmh_reg, ZMMReg) 879aecd6f8SChao Peng 889aecd6f8SChao Peng #ifdef TARGET_X86_64 899aecd6f8SChao Peng static const VMStateDescription vmstate_hi16_zmm_reg = { 909aecd6f8SChao Peng .name = "hi16_zmm_reg", 919aecd6f8SChao Peng .version_id = 1, 929aecd6f8SChao Peng .minimum_version_id = 1, 939aecd6f8SChao Peng .fields = (VMStateField[]) { 9419cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(0), ZMMReg), 9519cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(1), ZMMReg), 9619cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(2), ZMMReg), 9719cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(3), ZMMReg), 9819cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(4), ZMMReg), 9919cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(5), ZMMReg), 10019cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(6), ZMMReg), 10119cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(7), ZMMReg), 1029aecd6f8SChao Peng VMSTATE_END_OF_LIST() 1039aecd6f8SChao Peng } 1049aecd6f8SChao Peng }; 1059aecd6f8SChao Peng 106a03c3e90SPaolo Bonzini #define VMSTATE_Hi16_ZMM_REGS_VARS(_field, _state, _start) \ 107a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 108fa451874SEduardo Habkost vmstate_hi16_zmm_reg, ZMMReg) 1099aecd6f8SChao Peng #endif 1109aecd6f8SChao Peng 11179e9ebebSLiu Jinsong static const VMStateDescription vmstate_bnd_regs = { 11279e9ebebSLiu Jinsong .name = "bnd_regs", 11379e9ebebSLiu Jinsong .version_id = 1, 11479e9ebebSLiu Jinsong .minimum_version_id = 1, 11579e9ebebSLiu Jinsong .fields = (VMStateField[]) { 11679e9ebebSLiu Jinsong VMSTATE_UINT64(lb, BNDReg), 11779e9ebebSLiu Jinsong VMSTATE_UINT64(ub, BNDReg), 11879e9ebebSLiu Jinsong VMSTATE_END_OF_LIST() 11979e9ebebSLiu Jinsong } 12079e9ebebSLiu Jinsong }; 12179e9ebebSLiu Jinsong 12279e9ebebSLiu Jinsong #define VMSTATE_BND_REGS(_field, _state, _n) \ 12379e9ebebSLiu Jinsong VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_bnd_regs, BNDReg) 12479e9ebebSLiu Jinsong 125216c07c3SJuan Quintela static const VMStateDescription vmstate_mtrr_var = { 126216c07c3SJuan Quintela .name = "mtrr_var", 127216c07c3SJuan Quintela .version_id = 1, 128216c07c3SJuan Quintela .minimum_version_id = 1, 129216c07c3SJuan Quintela .fields = (VMStateField[]) { 130216c07c3SJuan Quintela VMSTATE_UINT64(base, MTRRVar), 131216c07c3SJuan Quintela VMSTATE_UINT64(mask, MTRRVar), 132216c07c3SJuan Quintela VMSTATE_END_OF_LIST() 133216c07c3SJuan Quintela } 134216c07c3SJuan Quintela }; 135216c07c3SJuan Quintela 1360cb892aaSJuan Quintela #define VMSTATE_MTRR_VARS(_field, _state, _n, _v) \ 1370cb892aaSJuan Quintela VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar) 138216c07c3SJuan Quintela 139*ab808276SDr. David Alan Gilbert typedef struct x86_FPReg_tmp { 140*ab808276SDr. David Alan Gilbert FPReg *parent; 141*ab808276SDr. David Alan Gilbert uint64_t tmp_mant; 142*ab808276SDr. David Alan Gilbert uint16_t tmp_exp; 143*ab808276SDr. David Alan Gilbert } x86_FPReg_tmp; 1443c8ce630SJuan Quintela 145*ab808276SDr. David Alan Gilbert static void fpreg_pre_save(void *opaque) 1463c8ce630SJuan Quintela { 147*ab808276SDr. David Alan Gilbert x86_FPReg_tmp *tmp = opaque; 148*ab808276SDr. David Alan Gilbert 1493c8ce630SJuan Quintela /* we save the real CPU data (in case of MMX usage only 'mant' 1503c8ce630SJuan Quintela contains the MMX register */ 151*ab808276SDr. David Alan Gilbert cpu_get_fp80(&tmp->tmp_mant, &tmp->tmp_exp, tmp->parent->d); 152*ab808276SDr. David Alan Gilbert } 1532c21ee76SJianjun Duan 154*ab808276SDr. David Alan Gilbert static int fpreg_post_load(void *opaque, int version) 155*ab808276SDr. David Alan Gilbert { 156*ab808276SDr. David Alan Gilbert x86_FPReg_tmp *tmp = opaque; 157*ab808276SDr. David Alan Gilbert 158*ab808276SDr. David Alan Gilbert tmp->parent->d = cpu_set_fp80(tmp->tmp_mant, tmp->tmp_exp); 1592c21ee76SJianjun Duan return 0; 1603c8ce630SJuan Quintela } 1613c8ce630SJuan Quintela 162*ab808276SDr. David Alan Gilbert static const VMStateDescription vmstate_fpreg_tmp = { 163*ab808276SDr. David Alan Gilbert .name = "fpreg_tmp", 164*ab808276SDr. David Alan Gilbert .post_load = fpreg_post_load, 165*ab808276SDr. David Alan Gilbert .pre_save = fpreg_pre_save, 166*ab808276SDr. David Alan Gilbert .fields = (VMStateField[]) { 167*ab808276SDr. David Alan Gilbert VMSTATE_UINT64(tmp_mant, x86_FPReg_tmp), 168*ab808276SDr. David Alan Gilbert VMSTATE_UINT16(tmp_exp, x86_FPReg_tmp), 169*ab808276SDr. David Alan Gilbert VMSTATE_END_OF_LIST() 170*ab808276SDr. David Alan Gilbert } 171*ab808276SDr. David Alan Gilbert }; 172*ab808276SDr. David Alan Gilbert 173*ab808276SDr. David Alan Gilbert static const VMStateDescription vmstate_fpreg = { 1740cb892aaSJuan Quintela .name = "fpreg", 175*ab808276SDr. David Alan Gilbert .fields = (VMStateField[]) { 176*ab808276SDr. David Alan Gilbert VMSTATE_WITH_TMP(FPReg, x86_FPReg_tmp, vmstate_fpreg_tmp), 177*ab808276SDr. David Alan Gilbert VMSTATE_END_OF_LIST() 178*ab808276SDr. David Alan Gilbert } 1790cb892aaSJuan Quintela }; 1800cb892aaSJuan Quintela 1810cb892aaSJuan Quintela static bool version_is_5(void *opaque, int version_id) 1820cb892aaSJuan Quintela { 1830cb892aaSJuan Quintela return version_id == 5; 1840cb892aaSJuan Quintela } 1850cb892aaSJuan Quintela 1860cb892aaSJuan Quintela #ifdef TARGET_X86_64 1870cb892aaSJuan Quintela static bool less_than_7(void *opaque, int version_id) 1880cb892aaSJuan Quintela { 1890cb892aaSJuan Quintela return version_id < 7; 1900cb892aaSJuan Quintela } 1910cb892aaSJuan Quintela 1922c21ee76SJianjun Duan static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size, 1932c21ee76SJianjun Duan VMStateField *field) 1940cb892aaSJuan Quintela { 1950cb892aaSJuan Quintela uint64_t *v = pv; 1960cb892aaSJuan Quintela *v = qemu_get_be32(f); 1970cb892aaSJuan Quintela return 0; 1980cb892aaSJuan Quintela } 1990cb892aaSJuan Quintela 2002c21ee76SJianjun Duan static int put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size, 2012c21ee76SJianjun Duan VMStateField *field, QJSON *vmdesc) 2020cb892aaSJuan Quintela { 2030cb892aaSJuan Quintela uint64_t *v = pv; 2040cb892aaSJuan Quintela qemu_put_be32(f, *v); 2052c21ee76SJianjun Duan 2062c21ee76SJianjun Duan return 0; 2070cb892aaSJuan Quintela } 2080cb892aaSJuan Quintela 209976b2037SBlue Swirl static const VMStateInfo vmstate_hack_uint64_as_uint32 = { 2100cb892aaSJuan Quintela .name = "uint64_as_uint32", 2110cb892aaSJuan Quintela .get = get_uint64_as_uint32, 2120cb892aaSJuan Quintela .put = put_uint64_as_uint32, 2130cb892aaSJuan Quintela }; 2140cb892aaSJuan Quintela 2150cb892aaSJuan Quintela #define VMSTATE_HACK_UINT32(_f, _s, _t) \ 216d4829d49SJuan Quintela VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint64_as_uint32, uint64_t) 2170cb892aaSJuan Quintela #endif 2180cb892aaSJuan Quintela 219c4c38c8cSJuan Quintela static void cpu_pre_save(void *opaque) 2208dd3dca3Saurel32 { 221f56e3a14SAndreas Färber X86CPU *cpu = opaque; 222f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 2230e607a80SJan Kiszka int i; 2248dd3dca3Saurel32 2258dd3dca3Saurel32 /* FPU */ 22667b8f419SJuan Quintela env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; 227cdc0c58fSJuan Quintela env->fptag_vmstate = 0; 2288dd3dca3Saurel32 for(i = 0; i < 8; i++) { 229cdc0c58fSJuan Quintela env->fptag_vmstate |= ((!env->fptags[i]) << i); 2308dd3dca3Saurel32 } 2318dd3dca3Saurel32 23260a902f1SJuan Quintela env->fpregs_format_vmstate = 0; 2333e47c249SOrit Wasserman 2343e47c249SOrit Wasserman /* 2353e47c249SOrit Wasserman * Real mode guest segments register DPL should be zero. 2363e47c249SOrit Wasserman * Older KVM version were setting it wrongly. 2373e47c249SOrit Wasserman * Fixing it will allow live migration to host with unrestricted guest 2383e47c249SOrit Wasserman * support (otherwise the migration will fail with invalid guest state 2393e47c249SOrit Wasserman * error). 2403e47c249SOrit Wasserman */ 2413e47c249SOrit Wasserman if (!(env->cr[0] & CR0_PE_MASK) && 2423e47c249SOrit Wasserman (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { 2433e47c249SOrit Wasserman env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); 2443e47c249SOrit Wasserman env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); 2453e47c249SOrit Wasserman env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); 2463e47c249SOrit Wasserman env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); 2473e47c249SOrit Wasserman env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); 2483e47c249SOrit Wasserman env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); 2493e47c249SOrit Wasserman } 2503e47c249SOrit Wasserman 251c4c38c8cSJuan Quintela } 252c4c38c8cSJuan Quintela 253468f6581SJuan Quintela static int cpu_post_load(void *opaque, int version_id) 254468f6581SJuan Quintela { 255f56e3a14SAndreas Färber X86CPU *cpu = opaque; 25675a34036SAndreas Färber CPUState *cs = CPU(cpu); 257f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 258468f6581SJuan Quintela int i; 259468f6581SJuan Quintela 26036f96c4bSHaozhong Zhang if (env->tsc_khz && env->user_tsc_khz && 26136f96c4bSHaozhong Zhang env->tsc_khz != env->user_tsc_khz) { 26236f96c4bSHaozhong Zhang error_report("Mismatch between user-specified TSC frequency and " 26336f96c4bSHaozhong Zhang "migrated TSC frequency"); 26436f96c4bSHaozhong Zhang return -EINVAL; 26536f96c4bSHaozhong Zhang } 26636f96c4bSHaozhong Zhang 26746baa900SDr. David Alan Gilbert if (env->fpregs_format_vmstate) { 26846baa900SDr. David Alan Gilbert error_report("Unsupported old non-softfloat CPU state"); 26946baa900SDr. David Alan Gilbert return -EINVAL; 27046baa900SDr. David Alan Gilbert } 271444ba679SOrit Wasserman /* 272444ba679SOrit Wasserman * Real mode guest segments register DPL should be zero. 273444ba679SOrit Wasserman * Older KVM version were setting it wrongly. 274444ba679SOrit Wasserman * Fixing it will allow live migration from such host that don't have 275444ba679SOrit Wasserman * restricted guest support to a host with unrestricted guest support 276444ba679SOrit Wasserman * (otherwise the migration will fail with invalid guest state 277444ba679SOrit Wasserman * error). 278444ba679SOrit Wasserman */ 279444ba679SOrit Wasserman if (!(env->cr[0] & CR0_PE_MASK) && 280444ba679SOrit Wasserman (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { 281444ba679SOrit Wasserman env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); 282444ba679SOrit Wasserman env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); 283444ba679SOrit Wasserman env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); 284444ba679SOrit Wasserman env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); 285444ba679SOrit Wasserman env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); 286444ba679SOrit Wasserman env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); 287444ba679SOrit Wasserman } 288444ba679SOrit Wasserman 2897125c937SPaolo Bonzini /* Older versions of QEMU incorrectly used CS.DPL as the CPL when 2907125c937SPaolo Bonzini * running under KVM. This is wrong for conforming code segments. 2917125c937SPaolo Bonzini * Luckily, in our implementation the CPL field of hflags is redundant 2927125c937SPaolo Bonzini * and we can get the right value from the SS descriptor privilege level. 2937125c937SPaolo Bonzini */ 2947125c937SPaolo Bonzini env->hflags &= ~HF_CPL_MASK; 2957125c937SPaolo Bonzini env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK; 2967125c937SPaolo Bonzini 297468f6581SJuan Quintela env->fpstt = (env->fpus_vmstate >> 11) & 7; 298468f6581SJuan Quintela env->fpus = env->fpus_vmstate & ~0x3800; 299468f6581SJuan Quintela env->fptag_vmstate ^= 0xff; 300468f6581SJuan Quintela for(i = 0; i < 8; i++) { 301468f6581SJuan Quintela env->fptags[i] = (env->fptag_vmstate >> i) & 1; 302468f6581SJuan Quintela } 3035bde1407SPavel Dovgalyuk update_fp_status(env); 304468f6581SJuan Quintela 305b3310ab3SAndreas Färber cpu_breakpoint_remove_all(cs, BP_CPU); 30675a34036SAndreas Färber cpu_watchpoint_remove_all(cs, BP_CPU); 30793d00d0fSRichard Henderson { 30893d00d0fSRichard Henderson /* Indicate all breakpoints disabled, as they are, then 30993d00d0fSRichard Henderson let the helper re-enable them. */ 31093d00d0fSRichard Henderson target_ulong dr7 = env->dr[7]; 31193d00d0fSRichard Henderson env->dr[7] = dr7 & ~(DR7_GLOBAL_BP_MASK | DR7_LOCAL_BP_MASK); 31293d00d0fSRichard Henderson cpu_x86_update_dr7(env, dr7); 313428065ceSliguang } 314d10eb08fSAlex Bennée tlb_flush(cs); 315428065ceSliguang 316f809c605SPaolo Bonzini if (tcg_enabled()) { 317f809c605SPaolo Bonzini cpu_smm_update(cpu); 318f809c605SPaolo Bonzini } 3191e7fbc6dSJuan Quintela return 0; 320468f6581SJuan Quintela } 321468f6581SJuan Quintela 322f6584ee2SGleb Natapov static bool async_pf_msr_needed(void *opaque) 323f6584ee2SGleb Natapov { 324f56e3a14SAndreas Färber X86CPU *cpu = opaque; 325f6584ee2SGleb Natapov 326f56e3a14SAndreas Färber return cpu->env.async_pf_en_msr != 0; 327f6584ee2SGleb Natapov } 328f6584ee2SGleb Natapov 329bc9a839dSMichael S. Tsirkin static bool pv_eoi_msr_needed(void *opaque) 330bc9a839dSMichael S. Tsirkin { 331f56e3a14SAndreas Färber X86CPU *cpu = opaque; 332bc9a839dSMichael S. Tsirkin 333f56e3a14SAndreas Färber return cpu->env.pv_eoi_en_msr != 0; 334bc9a839dSMichael S. Tsirkin } 335bc9a839dSMichael S. Tsirkin 336917367aaSMarcelo Tosatti static bool steal_time_msr_needed(void *opaque) 337917367aaSMarcelo Tosatti { 3380e503577SMarcelo Tosatti X86CPU *cpu = opaque; 339917367aaSMarcelo Tosatti 3400e503577SMarcelo Tosatti return cpu->env.steal_time_msr != 0; 341917367aaSMarcelo Tosatti } 342917367aaSMarcelo Tosatti 343917367aaSMarcelo Tosatti static const VMStateDescription vmstate_steal_time_msr = { 344917367aaSMarcelo Tosatti .name = "cpu/steal_time_msr", 345917367aaSMarcelo Tosatti .version_id = 1, 346917367aaSMarcelo Tosatti .minimum_version_id = 1, 3475cd8cadaSJuan Quintela .needed = steal_time_msr_needed, 348917367aaSMarcelo Tosatti .fields = (VMStateField[]) { 3490e503577SMarcelo Tosatti VMSTATE_UINT64(env.steal_time_msr, X86CPU), 350917367aaSMarcelo Tosatti VMSTATE_END_OF_LIST() 351917367aaSMarcelo Tosatti } 352917367aaSMarcelo Tosatti }; 353917367aaSMarcelo Tosatti 354f6584ee2SGleb Natapov static const VMStateDescription vmstate_async_pf_msr = { 355f6584ee2SGleb Natapov .name = "cpu/async_pf_msr", 356f6584ee2SGleb Natapov .version_id = 1, 357f6584ee2SGleb Natapov .minimum_version_id = 1, 3585cd8cadaSJuan Quintela .needed = async_pf_msr_needed, 359f6584ee2SGleb Natapov .fields = (VMStateField[]) { 360f56e3a14SAndreas Färber VMSTATE_UINT64(env.async_pf_en_msr, X86CPU), 361f6584ee2SGleb Natapov VMSTATE_END_OF_LIST() 362f6584ee2SGleb Natapov } 363f6584ee2SGleb Natapov }; 364f6584ee2SGleb Natapov 365bc9a839dSMichael S. Tsirkin static const VMStateDescription vmstate_pv_eoi_msr = { 366bc9a839dSMichael S. Tsirkin .name = "cpu/async_pv_eoi_msr", 367bc9a839dSMichael S. Tsirkin .version_id = 1, 368bc9a839dSMichael S. Tsirkin .minimum_version_id = 1, 3695cd8cadaSJuan Quintela .needed = pv_eoi_msr_needed, 370bc9a839dSMichael S. Tsirkin .fields = (VMStateField[]) { 371f56e3a14SAndreas Färber VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU), 372bc9a839dSMichael S. Tsirkin VMSTATE_END_OF_LIST() 373bc9a839dSMichael S. Tsirkin } 374bc9a839dSMichael S. Tsirkin }; 375bc9a839dSMichael S. Tsirkin 37642cc8fa6SJan Kiszka static bool fpop_ip_dp_needed(void *opaque) 37742cc8fa6SJan Kiszka { 378f56e3a14SAndreas Färber X86CPU *cpu = opaque; 379f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 38042cc8fa6SJan Kiszka 38142cc8fa6SJan Kiszka return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0; 38242cc8fa6SJan Kiszka } 38342cc8fa6SJan Kiszka 38442cc8fa6SJan Kiszka static const VMStateDescription vmstate_fpop_ip_dp = { 38542cc8fa6SJan Kiszka .name = "cpu/fpop_ip_dp", 38642cc8fa6SJan Kiszka .version_id = 1, 38742cc8fa6SJan Kiszka .minimum_version_id = 1, 3885cd8cadaSJuan Quintela .needed = fpop_ip_dp_needed, 38942cc8fa6SJan Kiszka .fields = (VMStateField[]) { 390f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpop, X86CPU), 391f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpip, X86CPU), 392f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpdp, X86CPU), 39342cc8fa6SJan Kiszka VMSTATE_END_OF_LIST() 39442cc8fa6SJan Kiszka } 39542cc8fa6SJan Kiszka }; 39642cc8fa6SJan Kiszka 397f28558d3SWill Auld static bool tsc_adjust_needed(void *opaque) 398f28558d3SWill Auld { 399f56e3a14SAndreas Färber X86CPU *cpu = opaque; 400f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 401f28558d3SWill Auld 402f28558d3SWill Auld return env->tsc_adjust != 0; 403f28558d3SWill Auld } 404f28558d3SWill Auld 405f28558d3SWill Auld static const VMStateDescription vmstate_msr_tsc_adjust = { 406f28558d3SWill Auld .name = "cpu/msr_tsc_adjust", 407f28558d3SWill Auld .version_id = 1, 408f28558d3SWill Auld .minimum_version_id = 1, 4095cd8cadaSJuan Quintela .needed = tsc_adjust_needed, 410f28558d3SWill Auld .fields = (VMStateField[]) { 411f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_adjust, X86CPU), 412f28558d3SWill Auld VMSTATE_END_OF_LIST() 413f28558d3SWill Auld } 414f28558d3SWill Auld }; 415f28558d3SWill Auld 416aa82ba54SLiu, Jinsong static bool tscdeadline_needed(void *opaque) 417aa82ba54SLiu, Jinsong { 418f56e3a14SAndreas Färber X86CPU *cpu = opaque; 419f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 420aa82ba54SLiu, Jinsong 421aa82ba54SLiu, Jinsong return env->tsc_deadline != 0; 422aa82ba54SLiu, Jinsong } 423aa82ba54SLiu, Jinsong 424aa82ba54SLiu, Jinsong static const VMStateDescription vmstate_msr_tscdeadline = { 425aa82ba54SLiu, Jinsong .name = "cpu/msr_tscdeadline", 426aa82ba54SLiu, Jinsong .version_id = 1, 427aa82ba54SLiu, Jinsong .minimum_version_id = 1, 4285cd8cadaSJuan Quintela .needed = tscdeadline_needed, 429aa82ba54SLiu, Jinsong .fields = (VMStateField[]) { 430f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_deadline, X86CPU), 431aa82ba54SLiu, Jinsong VMSTATE_END_OF_LIST() 432aa82ba54SLiu, Jinsong } 433aa82ba54SLiu, Jinsong }; 434aa82ba54SLiu, Jinsong 43521e87c46SAvi Kivity static bool misc_enable_needed(void *opaque) 43621e87c46SAvi Kivity { 437f56e3a14SAndreas Färber X86CPU *cpu = opaque; 438f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 43921e87c46SAvi Kivity 44021e87c46SAvi Kivity return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT; 44121e87c46SAvi Kivity } 44221e87c46SAvi Kivity 4430779caebSArthur Chunqi Li static bool feature_control_needed(void *opaque) 4440779caebSArthur Chunqi Li { 4450779caebSArthur Chunqi Li X86CPU *cpu = opaque; 4460779caebSArthur Chunqi Li CPUX86State *env = &cpu->env; 4470779caebSArthur Chunqi Li 4480779caebSArthur Chunqi Li return env->msr_ia32_feature_control != 0; 4490779caebSArthur Chunqi Li } 4500779caebSArthur Chunqi Li 45121e87c46SAvi Kivity static const VMStateDescription vmstate_msr_ia32_misc_enable = { 45221e87c46SAvi Kivity .name = "cpu/msr_ia32_misc_enable", 45321e87c46SAvi Kivity .version_id = 1, 45421e87c46SAvi Kivity .minimum_version_id = 1, 4555cd8cadaSJuan Quintela .needed = misc_enable_needed, 45621e87c46SAvi Kivity .fields = (VMStateField[]) { 457f56e3a14SAndreas Färber VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU), 45821e87c46SAvi Kivity VMSTATE_END_OF_LIST() 45921e87c46SAvi Kivity } 46021e87c46SAvi Kivity }; 46121e87c46SAvi Kivity 4620779caebSArthur Chunqi Li static const VMStateDescription vmstate_msr_ia32_feature_control = { 4630779caebSArthur Chunqi Li .name = "cpu/msr_ia32_feature_control", 4640779caebSArthur Chunqi Li .version_id = 1, 4650779caebSArthur Chunqi Li .minimum_version_id = 1, 4665cd8cadaSJuan Quintela .needed = feature_control_needed, 4670779caebSArthur Chunqi Li .fields = (VMStateField[]) { 4680779caebSArthur Chunqi Li VMSTATE_UINT64(env.msr_ia32_feature_control, X86CPU), 4690779caebSArthur Chunqi Li VMSTATE_END_OF_LIST() 4700779caebSArthur Chunqi Li } 4710779caebSArthur Chunqi Li }; 4720779caebSArthur Chunqi Li 4730d894367SPaolo Bonzini static bool pmu_enable_needed(void *opaque) 4740d894367SPaolo Bonzini { 4750d894367SPaolo Bonzini X86CPU *cpu = opaque; 4760d894367SPaolo Bonzini CPUX86State *env = &cpu->env; 4770d894367SPaolo Bonzini int i; 4780d894367SPaolo Bonzini 4790d894367SPaolo Bonzini if (env->msr_fixed_ctr_ctrl || env->msr_global_ctrl || 4800d894367SPaolo Bonzini env->msr_global_status || env->msr_global_ovf_ctrl) { 4810d894367SPaolo Bonzini return true; 4820d894367SPaolo Bonzini } 4830d894367SPaolo Bonzini for (i = 0; i < MAX_FIXED_COUNTERS; i++) { 4840d894367SPaolo Bonzini if (env->msr_fixed_counters[i]) { 4850d894367SPaolo Bonzini return true; 4860d894367SPaolo Bonzini } 4870d894367SPaolo Bonzini } 4880d894367SPaolo Bonzini for (i = 0; i < MAX_GP_COUNTERS; i++) { 4890d894367SPaolo Bonzini if (env->msr_gp_counters[i] || env->msr_gp_evtsel[i]) { 4900d894367SPaolo Bonzini return true; 4910d894367SPaolo Bonzini } 4920d894367SPaolo Bonzini } 4930d894367SPaolo Bonzini 4940d894367SPaolo Bonzini return false; 4950d894367SPaolo Bonzini } 4960d894367SPaolo Bonzini 4970d894367SPaolo Bonzini static const VMStateDescription vmstate_msr_architectural_pmu = { 4980d894367SPaolo Bonzini .name = "cpu/msr_architectural_pmu", 4990d894367SPaolo Bonzini .version_id = 1, 5000d894367SPaolo Bonzini .minimum_version_id = 1, 5015cd8cadaSJuan Quintela .needed = pmu_enable_needed, 5020d894367SPaolo Bonzini .fields = (VMStateField[]) { 5030d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_fixed_ctr_ctrl, X86CPU), 5040d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ctrl, X86CPU), 5050d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_status, X86CPU), 5060d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ovf_ctrl, X86CPU), 5070d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_fixed_counters, X86CPU, MAX_FIXED_COUNTERS), 5080d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_counters, X86CPU, MAX_GP_COUNTERS), 5090d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_evtsel, X86CPU, MAX_GP_COUNTERS), 5100d894367SPaolo Bonzini VMSTATE_END_OF_LIST() 5110d894367SPaolo Bonzini } 5120d894367SPaolo Bonzini }; 5130d894367SPaolo Bonzini 51479e9ebebSLiu Jinsong static bool mpx_needed(void *opaque) 51579e9ebebSLiu Jinsong { 51679e9ebebSLiu Jinsong X86CPU *cpu = opaque; 51779e9ebebSLiu Jinsong CPUX86State *env = &cpu->env; 51879e9ebebSLiu Jinsong unsigned int i; 51979e9ebebSLiu Jinsong 52079e9ebebSLiu Jinsong for (i = 0; i < 4; i++) { 52179e9ebebSLiu Jinsong if (env->bnd_regs[i].lb || env->bnd_regs[i].ub) { 52279e9ebebSLiu Jinsong return true; 52379e9ebebSLiu Jinsong } 52479e9ebebSLiu Jinsong } 52579e9ebebSLiu Jinsong 52679e9ebebSLiu Jinsong if (env->bndcs_regs.cfgu || env->bndcs_regs.sts) { 52779e9ebebSLiu Jinsong return true; 52879e9ebebSLiu Jinsong } 52979e9ebebSLiu Jinsong 53079e9ebebSLiu Jinsong return !!env->msr_bndcfgs; 53179e9ebebSLiu Jinsong } 53279e9ebebSLiu Jinsong 53379e9ebebSLiu Jinsong static const VMStateDescription vmstate_mpx = { 53479e9ebebSLiu Jinsong .name = "cpu/mpx", 53579e9ebebSLiu Jinsong .version_id = 1, 53679e9ebebSLiu Jinsong .minimum_version_id = 1, 5375cd8cadaSJuan Quintela .needed = mpx_needed, 53879e9ebebSLiu Jinsong .fields = (VMStateField[]) { 53979e9ebebSLiu Jinsong VMSTATE_BND_REGS(env.bnd_regs, X86CPU, 4), 54079e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.cfgu, X86CPU), 54179e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.sts, X86CPU), 54279e9ebebSLiu Jinsong VMSTATE_UINT64(env.msr_bndcfgs, X86CPU), 54379e9ebebSLiu Jinsong VMSTATE_END_OF_LIST() 54479e9ebebSLiu Jinsong } 54579e9ebebSLiu Jinsong }; 54679e9ebebSLiu Jinsong 5471c90ef26SVadim Rozenfeld static bool hyperv_hypercall_enable_needed(void *opaque) 5481c90ef26SVadim Rozenfeld { 5491c90ef26SVadim Rozenfeld X86CPU *cpu = opaque; 5501c90ef26SVadim Rozenfeld CPUX86State *env = &cpu->env; 5511c90ef26SVadim Rozenfeld 5521c90ef26SVadim Rozenfeld return env->msr_hv_hypercall != 0 || env->msr_hv_guest_os_id != 0; 5531c90ef26SVadim Rozenfeld } 5541c90ef26SVadim Rozenfeld 5551c90ef26SVadim Rozenfeld static const VMStateDescription vmstate_msr_hypercall_hypercall = { 5561c90ef26SVadim Rozenfeld .name = "cpu/msr_hyperv_hypercall", 5571c90ef26SVadim Rozenfeld .version_id = 1, 5581c90ef26SVadim Rozenfeld .minimum_version_id = 1, 5595cd8cadaSJuan Quintela .needed = hyperv_hypercall_enable_needed, 5601c90ef26SVadim Rozenfeld .fields = (VMStateField[]) { 5611c90ef26SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_guest_os_id, X86CPU), 562466e6e9dSPaolo Bonzini VMSTATE_UINT64(env.msr_hv_hypercall, X86CPU), 5631c90ef26SVadim Rozenfeld VMSTATE_END_OF_LIST() 5641c90ef26SVadim Rozenfeld } 5651c90ef26SVadim Rozenfeld }; 5661c90ef26SVadim Rozenfeld 5675ef68987SVadim Rozenfeld static bool hyperv_vapic_enable_needed(void *opaque) 5685ef68987SVadim Rozenfeld { 5695ef68987SVadim Rozenfeld X86CPU *cpu = opaque; 5705ef68987SVadim Rozenfeld CPUX86State *env = &cpu->env; 5715ef68987SVadim Rozenfeld 5725ef68987SVadim Rozenfeld return env->msr_hv_vapic != 0; 5735ef68987SVadim Rozenfeld } 5745ef68987SVadim Rozenfeld 5755ef68987SVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_vapic = { 5765ef68987SVadim Rozenfeld .name = "cpu/msr_hyperv_vapic", 5775ef68987SVadim Rozenfeld .version_id = 1, 5785ef68987SVadim Rozenfeld .minimum_version_id = 1, 5795cd8cadaSJuan Quintela .needed = hyperv_vapic_enable_needed, 5805ef68987SVadim Rozenfeld .fields = (VMStateField[]) { 5815ef68987SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_vapic, X86CPU), 5825ef68987SVadim Rozenfeld VMSTATE_END_OF_LIST() 5835ef68987SVadim Rozenfeld } 5845ef68987SVadim Rozenfeld }; 5855ef68987SVadim Rozenfeld 58648a5f3bcSVadim Rozenfeld static bool hyperv_time_enable_needed(void *opaque) 58748a5f3bcSVadim Rozenfeld { 58848a5f3bcSVadim Rozenfeld X86CPU *cpu = opaque; 58948a5f3bcSVadim Rozenfeld CPUX86State *env = &cpu->env; 59048a5f3bcSVadim Rozenfeld 59148a5f3bcSVadim Rozenfeld return env->msr_hv_tsc != 0; 59248a5f3bcSVadim Rozenfeld } 59348a5f3bcSVadim Rozenfeld 59448a5f3bcSVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_time = { 59548a5f3bcSVadim Rozenfeld .name = "cpu/msr_hyperv_time", 59648a5f3bcSVadim Rozenfeld .version_id = 1, 59748a5f3bcSVadim Rozenfeld .minimum_version_id = 1, 5985cd8cadaSJuan Quintela .needed = hyperv_time_enable_needed, 59948a5f3bcSVadim Rozenfeld .fields = (VMStateField[]) { 60048a5f3bcSVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_tsc, X86CPU), 60148a5f3bcSVadim Rozenfeld VMSTATE_END_OF_LIST() 60248a5f3bcSVadim Rozenfeld } 60348a5f3bcSVadim Rozenfeld }; 60448a5f3bcSVadim Rozenfeld 605f2a53c9eSAndrey Smetanin static bool hyperv_crash_enable_needed(void *opaque) 606f2a53c9eSAndrey Smetanin { 607f2a53c9eSAndrey Smetanin X86CPU *cpu = opaque; 608f2a53c9eSAndrey Smetanin CPUX86State *env = &cpu->env; 609f2a53c9eSAndrey Smetanin int i; 610f2a53c9eSAndrey Smetanin 611f2a53c9eSAndrey Smetanin for (i = 0; i < HV_X64_MSR_CRASH_PARAMS; i++) { 612f2a53c9eSAndrey Smetanin if (env->msr_hv_crash_params[i]) { 613f2a53c9eSAndrey Smetanin return true; 614f2a53c9eSAndrey Smetanin } 615f2a53c9eSAndrey Smetanin } 616f2a53c9eSAndrey Smetanin return false; 617f2a53c9eSAndrey Smetanin } 618f2a53c9eSAndrey Smetanin 619f2a53c9eSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_crash = { 620f2a53c9eSAndrey Smetanin .name = "cpu/msr_hyperv_crash", 621f2a53c9eSAndrey Smetanin .version_id = 1, 622f2a53c9eSAndrey Smetanin .minimum_version_id = 1, 623f2a53c9eSAndrey Smetanin .needed = hyperv_crash_enable_needed, 624f2a53c9eSAndrey Smetanin .fields = (VMStateField[]) { 625f2a53c9eSAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_crash_params, 626f2a53c9eSAndrey Smetanin X86CPU, HV_X64_MSR_CRASH_PARAMS), 627f2a53c9eSAndrey Smetanin VMSTATE_END_OF_LIST() 628f2a53c9eSAndrey Smetanin } 629f2a53c9eSAndrey Smetanin }; 630f2a53c9eSAndrey Smetanin 63146eb8f98SAndrey Smetanin static bool hyperv_runtime_enable_needed(void *opaque) 63246eb8f98SAndrey Smetanin { 63346eb8f98SAndrey Smetanin X86CPU *cpu = opaque; 63446eb8f98SAndrey Smetanin CPUX86State *env = &cpu->env; 63546eb8f98SAndrey Smetanin 63651227875SZhuangYanying if (!cpu->hyperv_runtime) { 63751227875SZhuangYanying return false; 63851227875SZhuangYanying } 63951227875SZhuangYanying 64046eb8f98SAndrey Smetanin return env->msr_hv_runtime != 0; 64146eb8f98SAndrey Smetanin } 64246eb8f98SAndrey Smetanin 64346eb8f98SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_runtime = { 64446eb8f98SAndrey Smetanin .name = "cpu/msr_hyperv_runtime", 64546eb8f98SAndrey Smetanin .version_id = 1, 64646eb8f98SAndrey Smetanin .minimum_version_id = 1, 64746eb8f98SAndrey Smetanin .needed = hyperv_runtime_enable_needed, 64846eb8f98SAndrey Smetanin .fields = (VMStateField[]) { 64946eb8f98SAndrey Smetanin VMSTATE_UINT64(env.msr_hv_runtime, X86CPU), 65046eb8f98SAndrey Smetanin VMSTATE_END_OF_LIST() 65146eb8f98SAndrey Smetanin } 65246eb8f98SAndrey Smetanin }; 65346eb8f98SAndrey Smetanin 654866eea9aSAndrey Smetanin static bool hyperv_synic_enable_needed(void *opaque) 655866eea9aSAndrey Smetanin { 656866eea9aSAndrey Smetanin X86CPU *cpu = opaque; 657866eea9aSAndrey Smetanin CPUX86State *env = &cpu->env; 658866eea9aSAndrey Smetanin int i; 659866eea9aSAndrey Smetanin 660866eea9aSAndrey Smetanin if (env->msr_hv_synic_control != 0 || 661866eea9aSAndrey Smetanin env->msr_hv_synic_evt_page != 0 || 662866eea9aSAndrey Smetanin env->msr_hv_synic_msg_page != 0) { 663866eea9aSAndrey Smetanin return true; 664866eea9aSAndrey Smetanin } 665866eea9aSAndrey Smetanin 666866eea9aSAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) { 667866eea9aSAndrey Smetanin if (env->msr_hv_synic_sint[i] != 0) { 668866eea9aSAndrey Smetanin return true; 669866eea9aSAndrey Smetanin } 670866eea9aSAndrey Smetanin } 671866eea9aSAndrey Smetanin 672866eea9aSAndrey Smetanin return false; 673866eea9aSAndrey Smetanin } 674866eea9aSAndrey Smetanin 675866eea9aSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_synic = { 676866eea9aSAndrey Smetanin .name = "cpu/msr_hyperv_synic", 677866eea9aSAndrey Smetanin .version_id = 1, 678866eea9aSAndrey Smetanin .minimum_version_id = 1, 679866eea9aSAndrey Smetanin .needed = hyperv_synic_enable_needed, 680866eea9aSAndrey Smetanin .fields = (VMStateField[]) { 681866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU), 682866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU), 683866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_msg_page, X86CPU), 684866eea9aSAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_synic_sint, X86CPU, 685866eea9aSAndrey Smetanin HV_SYNIC_SINT_COUNT), 686866eea9aSAndrey Smetanin VMSTATE_END_OF_LIST() 687866eea9aSAndrey Smetanin } 688866eea9aSAndrey Smetanin }; 689866eea9aSAndrey Smetanin 690ff99aa64SAndrey Smetanin static bool hyperv_stimer_enable_needed(void *opaque) 691ff99aa64SAndrey Smetanin { 692ff99aa64SAndrey Smetanin X86CPU *cpu = opaque; 693ff99aa64SAndrey Smetanin CPUX86State *env = &cpu->env; 694ff99aa64SAndrey Smetanin int i; 695ff99aa64SAndrey Smetanin 696ff99aa64SAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_stimer_config); i++) { 697ff99aa64SAndrey Smetanin if (env->msr_hv_stimer_config[i] || env->msr_hv_stimer_count[i]) { 698ff99aa64SAndrey Smetanin return true; 699ff99aa64SAndrey Smetanin } 700ff99aa64SAndrey Smetanin } 701ff99aa64SAndrey Smetanin return false; 702ff99aa64SAndrey Smetanin } 703ff99aa64SAndrey Smetanin 704ff99aa64SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_stimer = { 705ff99aa64SAndrey Smetanin .name = "cpu/msr_hyperv_stimer", 706ff99aa64SAndrey Smetanin .version_id = 1, 707ff99aa64SAndrey Smetanin .minimum_version_id = 1, 708ff99aa64SAndrey Smetanin .needed = hyperv_stimer_enable_needed, 709ff99aa64SAndrey Smetanin .fields = (VMStateField[]) { 710ff99aa64SAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_config, 711ff99aa64SAndrey Smetanin X86CPU, HV_SYNIC_STIMER_COUNT), 712ff99aa64SAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_count, 713ff99aa64SAndrey Smetanin X86CPU, HV_SYNIC_STIMER_COUNT), 714ff99aa64SAndrey Smetanin VMSTATE_END_OF_LIST() 715ff99aa64SAndrey Smetanin } 716ff99aa64SAndrey Smetanin }; 717ff99aa64SAndrey Smetanin 7189aecd6f8SChao Peng static bool avx512_needed(void *opaque) 7199aecd6f8SChao Peng { 7209aecd6f8SChao Peng X86CPU *cpu = opaque; 7219aecd6f8SChao Peng CPUX86State *env = &cpu->env; 7229aecd6f8SChao Peng unsigned int i; 7239aecd6f8SChao Peng 7249aecd6f8SChao Peng for (i = 0; i < NB_OPMASK_REGS; i++) { 7259aecd6f8SChao Peng if (env->opmask_regs[i]) { 7269aecd6f8SChao Peng return true; 7279aecd6f8SChao Peng } 7289aecd6f8SChao Peng } 7299aecd6f8SChao Peng 7309aecd6f8SChao Peng for (i = 0; i < CPU_NB_REGS; i++) { 73119cbd87cSEduardo Habkost #define ENV_XMM(reg, field) (env->xmm_regs[reg].ZMM_Q(field)) 732b7711471SPaolo Bonzini if (ENV_XMM(i, 4) || ENV_XMM(i, 6) || 733b7711471SPaolo Bonzini ENV_XMM(i, 5) || ENV_XMM(i, 7)) { 7349aecd6f8SChao Peng return true; 7359aecd6f8SChao Peng } 7369aecd6f8SChao Peng #ifdef TARGET_X86_64 737b7711471SPaolo Bonzini if (ENV_XMM(i+16, 0) || ENV_XMM(i+16, 1) || 738b7711471SPaolo Bonzini ENV_XMM(i+16, 2) || ENV_XMM(i+16, 3) || 739b7711471SPaolo Bonzini ENV_XMM(i+16, 4) || ENV_XMM(i+16, 5) || 740b7711471SPaolo Bonzini ENV_XMM(i+16, 6) || ENV_XMM(i+16, 7)) { 7419aecd6f8SChao Peng return true; 7429aecd6f8SChao Peng } 7439aecd6f8SChao Peng #endif 7449aecd6f8SChao Peng } 7459aecd6f8SChao Peng 7469aecd6f8SChao Peng return false; 7479aecd6f8SChao Peng } 7489aecd6f8SChao Peng 7499aecd6f8SChao Peng static const VMStateDescription vmstate_avx512 = { 7509aecd6f8SChao Peng .name = "cpu/avx512", 7519aecd6f8SChao Peng .version_id = 1, 7529aecd6f8SChao Peng .minimum_version_id = 1, 7535cd8cadaSJuan Quintela .needed = avx512_needed, 7549aecd6f8SChao Peng .fields = (VMStateField[]) { 7559aecd6f8SChao Peng VMSTATE_UINT64_ARRAY(env.opmask_regs, X86CPU, NB_OPMASK_REGS), 756b7711471SPaolo Bonzini VMSTATE_ZMMH_REGS_VARS(env.xmm_regs, X86CPU, 0), 7579aecd6f8SChao Peng #ifdef TARGET_X86_64 758b7711471SPaolo Bonzini VMSTATE_Hi16_ZMM_REGS_VARS(env.xmm_regs, X86CPU, 16), 7599aecd6f8SChao Peng #endif 7609aecd6f8SChao Peng VMSTATE_END_OF_LIST() 7619aecd6f8SChao Peng } 7629aecd6f8SChao Peng }; 7639aecd6f8SChao Peng 76418cd2c17SWanpeng Li static bool xss_needed(void *opaque) 76518cd2c17SWanpeng Li { 76618cd2c17SWanpeng Li X86CPU *cpu = opaque; 76718cd2c17SWanpeng Li CPUX86State *env = &cpu->env; 76818cd2c17SWanpeng Li 76918cd2c17SWanpeng Li return env->xss != 0; 77018cd2c17SWanpeng Li } 77118cd2c17SWanpeng Li 77218cd2c17SWanpeng Li static const VMStateDescription vmstate_xss = { 77318cd2c17SWanpeng Li .name = "cpu/xss", 77418cd2c17SWanpeng Li .version_id = 1, 77518cd2c17SWanpeng Li .minimum_version_id = 1, 7765cd8cadaSJuan Quintela .needed = xss_needed, 77718cd2c17SWanpeng Li .fields = (VMStateField[]) { 77818cd2c17SWanpeng Li VMSTATE_UINT64(env.xss, X86CPU), 77918cd2c17SWanpeng Li VMSTATE_END_OF_LIST() 78018cd2c17SWanpeng Li } 78118cd2c17SWanpeng Li }; 78218cd2c17SWanpeng Li 783f74eefe0SHuaitong Han #ifdef TARGET_X86_64 784f74eefe0SHuaitong Han static bool pkru_needed(void *opaque) 785f74eefe0SHuaitong Han { 786f74eefe0SHuaitong Han X86CPU *cpu = opaque; 787f74eefe0SHuaitong Han CPUX86State *env = &cpu->env; 788f74eefe0SHuaitong Han 789f74eefe0SHuaitong Han return env->pkru != 0; 790f74eefe0SHuaitong Han } 791f74eefe0SHuaitong Han 792f74eefe0SHuaitong Han static const VMStateDescription vmstate_pkru = { 793f74eefe0SHuaitong Han .name = "cpu/pkru", 794f74eefe0SHuaitong Han .version_id = 1, 795f74eefe0SHuaitong Han .minimum_version_id = 1, 796f74eefe0SHuaitong Han .needed = pkru_needed, 797f74eefe0SHuaitong Han .fields = (VMStateField[]){ 798f74eefe0SHuaitong Han VMSTATE_UINT32(env.pkru, X86CPU), 799f74eefe0SHuaitong Han VMSTATE_END_OF_LIST() 800f74eefe0SHuaitong Han } 801f74eefe0SHuaitong Han }; 802f74eefe0SHuaitong Han #endif 803f74eefe0SHuaitong Han 80436f96c4bSHaozhong Zhang static bool tsc_khz_needed(void *opaque) 80536f96c4bSHaozhong Zhang { 80636f96c4bSHaozhong Zhang X86CPU *cpu = opaque; 80736f96c4bSHaozhong Zhang CPUX86State *env = &cpu->env; 80836f96c4bSHaozhong Zhang MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); 80936f96c4bSHaozhong Zhang PCMachineClass *pcmc = PC_MACHINE_CLASS(mc); 81036f96c4bSHaozhong Zhang return env->tsc_khz && pcmc->save_tsc_khz; 81136f96c4bSHaozhong Zhang } 81236f96c4bSHaozhong Zhang 81336f96c4bSHaozhong Zhang static const VMStateDescription vmstate_tsc_khz = { 81436f96c4bSHaozhong Zhang .name = "cpu/tsc_khz", 81536f96c4bSHaozhong Zhang .version_id = 1, 81636f96c4bSHaozhong Zhang .minimum_version_id = 1, 81736f96c4bSHaozhong Zhang .needed = tsc_khz_needed, 81836f96c4bSHaozhong Zhang .fields = (VMStateField[]) { 81936f96c4bSHaozhong Zhang VMSTATE_INT64(env.tsc_khz, X86CPU), 82036f96c4bSHaozhong Zhang VMSTATE_END_OF_LIST() 82136f96c4bSHaozhong Zhang } 82236f96c4bSHaozhong Zhang }; 82336f96c4bSHaozhong Zhang 82487f8b626SAshok Raj static bool mcg_ext_ctl_needed(void *opaque) 82587f8b626SAshok Raj { 82687f8b626SAshok Raj X86CPU *cpu = opaque; 82787f8b626SAshok Raj CPUX86State *env = &cpu->env; 82887f8b626SAshok Raj return cpu->enable_lmce && env->mcg_ext_ctl; 82987f8b626SAshok Raj } 83087f8b626SAshok Raj 83187f8b626SAshok Raj static const VMStateDescription vmstate_mcg_ext_ctl = { 83287f8b626SAshok Raj .name = "cpu/mcg_ext_ctl", 83387f8b626SAshok Raj .version_id = 1, 83487f8b626SAshok Raj .minimum_version_id = 1, 83587f8b626SAshok Raj .needed = mcg_ext_ctl_needed, 83687f8b626SAshok Raj .fields = (VMStateField[]) { 83787f8b626SAshok Raj VMSTATE_UINT64(env.mcg_ext_ctl, X86CPU), 83887f8b626SAshok Raj VMSTATE_END_OF_LIST() 83987f8b626SAshok Raj } 84087f8b626SAshok Raj }; 84187f8b626SAshok Raj 84268bfd0adSMarcelo Tosatti VMStateDescription vmstate_x86_cpu = { 8430cb892aaSJuan Quintela .name = "cpu", 844f56e3a14SAndreas Färber .version_id = 12, 8450cb892aaSJuan Quintela .minimum_version_id = 3, 8460cb892aaSJuan Quintela .pre_save = cpu_pre_save, 8470cb892aaSJuan Quintela .post_load = cpu_post_load, 8480cb892aaSJuan Quintela .fields = (VMStateField[]) { 849f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS), 850f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eip, X86CPU), 851f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eflags, X86CPU), 852f56e3a14SAndreas Färber VMSTATE_UINT32(env.hflags, X86CPU), 8530cb892aaSJuan Quintela /* FPU */ 854f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpuc, X86CPU), 855f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpus_vmstate, X86CPU), 856f56e3a14SAndreas Färber VMSTATE_UINT16(env.fptag_vmstate, X86CPU), 857f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU), 85846baa900SDr. David Alan Gilbert 85946baa900SDr. David Alan Gilbert VMSTATE_STRUCT_ARRAY(env.fpregs, X86CPU, 8, 0, vmstate_fpreg, FPReg), 8608dd3dca3Saurel32 861f56e3a14SAndreas Färber VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6), 862f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.ldt, X86CPU), 863f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.tr, X86CPU), 864f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.gdt, X86CPU), 865f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.idt, X86CPU), 866468f6581SJuan Quintela 867f56e3a14SAndreas Färber VMSTATE_UINT32(env.sysenter_cs, X86CPU), 8680cb892aaSJuan Quintela #ifdef TARGET_X86_64 8690cb892aaSJuan Quintela /* Hack: In v7 size changed from 32 to 64 bits on x86_64 */ 870f56e3a14SAndreas Färber VMSTATE_HACK_UINT32(env.sysenter_esp, X86CPU, less_than_7), 871f56e3a14SAndreas Färber VMSTATE_HACK_UINT32(env.sysenter_eip, X86CPU, less_than_7), 872f56e3a14SAndreas Färber VMSTATE_UINTTL_V(env.sysenter_esp, X86CPU, 7), 873f56e3a14SAndreas Färber VMSTATE_UINTTL_V(env.sysenter_eip, X86CPU, 7), 8743c8ce630SJuan Quintela #else 875f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_esp, X86CPU), 876f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_eip, X86CPU), 8773c8ce630SJuan Quintela #endif 8788dd3dca3Saurel32 879f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[0], X86CPU), 880f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[2], X86CPU), 881f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[3], X86CPU), 882f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[4], X86CPU), 883f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8), 8840cb892aaSJuan Quintela /* MMU */ 885f56e3a14SAndreas Färber VMSTATE_INT32(env.a20_mask, X86CPU), 8860cb892aaSJuan Quintela /* XMM */ 887f56e3a14SAndreas Färber VMSTATE_UINT32(env.mxcsr, X86CPU), 888a03c3e90SPaolo Bonzini VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, 0), 8898dd3dca3Saurel32 8908dd3dca3Saurel32 #ifdef TARGET_X86_64 891f56e3a14SAndreas Färber VMSTATE_UINT64(env.efer, X86CPU), 892f56e3a14SAndreas Färber VMSTATE_UINT64(env.star, X86CPU), 893f56e3a14SAndreas Färber VMSTATE_UINT64(env.lstar, X86CPU), 894f56e3a14SAndreas Färber VMSTATE_UINT64(env.cstar, X86CPU), 895f56e3a14SAndreas Färber VMSTATE_UINT64(env.fmask, X86CPU), 896f56e3a14SAndreas Färber VMSTATE_UINT64(env.kernelgsbase, X86CPU), 8978dd3dca3Saurel32 #endif 898f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.smbase, X86CPU, 4), 8998dd3dca3Saurel32 900f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.pat, X86CPU, 5), 901f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.hflags2, X86CPU, 5), 902dd5e3b17Saliguori 903259186a7SAndreas Färber VMSTATE_UINT32_TEST(parent_obj.halted, X86CPU, version_is_5), 904f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.vm_hsave, X86CPU, 5), 905f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.vm_vmcb, X86CPU, 5), 906f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.tsc_offset, X86CPU, 5), 907f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.intercept, X86CPU, 5), 908f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_cr_read, X86CPU, 5), 909f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_cr_write, X86CPU, 5), 910f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_dr_read, X86CPU, 5), 911f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_dr_write, X86CPU, 5), 912f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.intercept_exceptions, X86CPU, 5), 913f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.v_tpr, X86CPU, 5), 914dd5e3b17Saliguori /* MTRRs */ 915f56e3a14SAndreas Färber VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8), 916f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8), 917d8b5c67bSAlex Williamson VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, MSR_MTRRcap_VCNT, 8), 9180cb892aaSJuan Quintela /* KVM-related states */ 919f56e3a14SAndreas Färber VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9), 920f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.mp_state, X86CPU, 9), 921f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.tsc, X86CPU, 9), 922f56e3a14SAndreas Färber VMSTATE_INT32_V(env.exception_injected, X86CPU, 11), 923f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.soft_interrupt, X86CPU, 11), 924f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.nmi_injected, X86CPU, 11), 925f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.nmi_pending, X86CPU, 11), 926f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.has_error_code, X86CPU, 11), 927f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.sipi_vector, X86CPU, 11), 9280cb892aaSJuan Quintela /* MCE */ 929f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mcg_cap, X86CPU, 10), 930f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mcg_status, X86CPU, 10), 931f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mcg_ctl, X86CPU, 10), 932f56e3a14SAndreas Färber VMSTATE_UINT64_ARRAY_V(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4, 10), 9330cb892aaSJuan Quintela /* rdtscp */ 934f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.tsc_aux, X86CPU, 11), 9351a03675dSGlauber Costa /* KVM pvclock msr */ 936f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.system_time_msr, X86CPU, 11), 937f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.wall_clock_msr, X86CPU, 11), 938f1665b21SSheng Yang /* XSAVE related fields */ 939f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xcr0, X86CPU, 12), 940f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12), 941b7711471SPaolo Bonzini VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, 0, 12), 9420cb892aaSJuan Quintela VMSTATE_END_OF_LIST() 943a0fb002cSJan Kiszka /* The above list is not sorted /wrt version numbers, watch out! */ 944f6584ee2SGleb Natapov }, 9455cd8cadaSJuan Quintela .subsections = (const VMStateDescription*[]) { 9465cd8cadaSJuan Quintela &vmstate_async_pf_msr, 9475cd8cadaSJuan Quintela &vmstate_pv_eoi_msr, 9485cd8cadaSJuan Quintela &vmstate_steal_time_msr, 9495cd8cadaSJuan Quintela &vmstate_fpop_ip_dp, 9505cd8cadaSJuan Quintela &vmstate_msr_tsc_adjust, 9515cd8cadaSJuan Quintela &vmstate_msr_tscdeadline, 9525cd8cadaSJuan Quintela &vmstate_msr_ia32_misc_enable, 9535cd8cadaSJuan Quintela &vmstate_msr_ia32_feature_control, 9545cd8cadaSJuan Quintela &vmstate_msr_architectural_pmu, 9555cd8cadaSJuan Quintela &vmstate_mpx, 9565cd8cadaSJuan Quintela &vmstate_msr_hypercall_hypercall, 9575cd8cadaSJuan Quintela &vmstate_msr_hyperv_vapic, 9585cd8cadaSJuan Quintela &vmstate_msr_hyperv_time, 959f2a53c9eSAndrey Smetanin &vmstate_msr_hyperv_crash, 96046eb8f98SAndrey Smetanin &vmstate_msr_hyperv_runtime, 961866eea9aSAndrey Smetanin &vmstate_msr_hyperv_synic, 962ff99aa64SAndrey Smetanin &vmstate_msr_hyperv_stimer, 9635cd8cadaSJuan Quintela &vmstate_avx512, 9645cd8cadaSJuan Quintela &vmstate_xss, 96536f96c4bSHaozhong Zhang &vmstate_tsc_khz, 966f74eefe0SHuaitong Han #ifdef TARGET_X86_64 967f74eefe0SHuaitong Han &vmstate_pkru, 968f74eefe0SHuaitong Han #endif 96987f8b626SAshok Raj &vmstate_mcg_ext_ctl, 9705cd8cadaSJuan Quintela NULL 971dd5e3b17Saliguori } 9720cb892aaSJuan Quintela }; 973