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 1392c21ee76SJianjun Duan static int get_fpreg(QEMUFile *f, void *opaque, size_t size, 1402c21ee76SJianjun Duan VMStateField *field) 1413c8ce630SJuan Quintela { 1423c8ce630SJuan Quintela FPReg *fp_reg = opaque; 1433c8ce630SJuan Quintela uint64_t mant; 1443c8ce630SJuan Quintela uint16_t exp; 1453c8ce630SJuan Quintela 1463c8ce630SJuan Quintela qemu_get_be64s(f, &mant); 1473c8ce630SJuan Quintela qemu_get_be16s(f, &exp); 1483c8ce630SJuan Quintela fp_reg->d = cpu_set_fp80(mant, exp); 1493c8ce630SJuan Quintela return 0; 1503c8ce630SJuan Quintela } 1513c8ce630SJuan Quintela 1522c21ee76SJianjun Duan static int put_fpreg(QEMUFile *f, void *opaque, size_t size, 1532c21ee76SJianjun Duan VMStateField *field, QJSON *vmdesc) 1543c8ce630SJuan Quintela { 1553c8ce630SJuan Quintela FPReg *fp_reg = opaque; 1563c8ce630SJuan Quintela uint64_t mant; 1573c8ce630SJuan Quintela uint16_t exp; 1583c8ce630SJuan Quintela /* we save the real CPU data (in case of MMX usage only 'mant' 1593c8ce630SJuan Quintela contains the MMX register */ 1603c8ce630SJuan Quintela cpu_get_fp80(&mant, &exp, fp_reg->d); 1613c8ce630SJuan Quintela qemu_put_be64s(f, &mant); 1623c8ce630SJuan Quintela qemu_put_be16s(f, &exp); 1632c21ee76SJianjun Duan 1642c21ee76SJianjun Duan return 0; 1653c8ce630SJuan Quintela } 1663c8ce630SJuan Quintela 167976b2037SBlue Swirl static const VMStateInfo vmstate_fpreg = { 1680cb892aaSJuan Quintela .name = "fpreg", 1690cb892aaSJuan Quintela .get = get_fpreg, 1700cb892aaSJuan Quintela .put = put_fpreg, 1710cb892aaSJuan Quintela }; 1720cb892aaSJuan Quintela 1730cb892aaSJuan Quintela static bool version_is_5(void *opaque, int version_id) 1740cb892aaSJuan Quintela { 1750cb892aaSJuan Quintela return version_id == 5; 1760cb892aaSJuan Quintela } 1770cb892aaSJuan Quintela 1780cb892aaSJuan Quintela #ifdef TARGET_X86_64 1790cb892aaSJuan Quintela static bool less_than_7(void *opaque, int version_id) 1800cb892aaSJuan Quintela { 1810cb892aaSJuan Quintela return version_id < 7; 1820cb892aaSJuan Quintela } 1830cb892aaSJuan Quintela 1842c21ee76SJianjun Duan static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size, 1852c21ee76SJianjun Duan VMStateField *field) 1860cb892aaSJuan Quintela { 1870cb892aaSJuan Quintela uint64_t *v = pv; 1880cb892aaSJuan Quintela *v = qemu_get_be32(f); 1890cb892aaSJuan Quintela return 0; 1900cb892aaSJuan Quintela } 1910cb892aaSJuan Quintela 1922c21ee76SJianjun Duan static int put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size, 1932c21ee76SJianjun Duan VMStateField *field, QJSON *vmdesc) 1940cb892aaSJuan Quintela { 1950cb892aaSJuan Quintela uint64_t *v = pv; 1960cb892aaSJuan Quintela qemu_put_be32(f, *v); 1972c21ee76SJianjun Duan 1982c21ee76SJianjun Duan return 0; 1990cb892aaSJuan Quintela } 2000cb892aaSJuan Quintela 201976b2037SBlue Swirl static const VMStateInfo vmstate_hack_uint64_as_uint32 = { 2020cb892aaSJuan Quintela .name = "uint64_as_uint32", 2030cb892aaSJuan Quintela .get = get_uint64_as_uint32, 2040cb892aaSJuan Quintela .put = put_uint64_as_uint32, 2050cb892aaSJuan Quintela }; 2060cb892aaSJuan Quintela 2070cb892aaSJuan Quintela #define VMSTATE_HACK_UINT32(_f, _s, _t) \ 208d4829d49SJuan Quintela VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint64_as_uint32, uint64_t) 2090cb892aaSJuan Quintela #endif 2100cb892aaSJuan Quintela 211c4c38c8cSJuan Quintela static void cpu_pre_save(void *opaque) 2128dd3dca3Saurel32 { 213f56e3a14SAndreas Färber X86CPU *cpu = opaque; 214f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 2150e607a80SJan Kiszka int i; 2168dd3dca3Saurel32 2178dd3dca3Saurel32 /* FPU */ 21867b8f419SJuan Quintela env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; 219cdc0c58fSJuan Quintela env->fptag_vmstate = 0; 2208dd3dca3Saurel32 for(i = 0; i < 8; i++) { 221cdc0c58fSJuan Quintela env->fptag_vmstate |= ((!env->fptags[i]) << i); 2228dd3dca3Saurel32 } 2238dd3dca3Saurel32 22460a902f1SJuan Quintela env->fpregs_format_vmstate = 0; 2253e47c249SOrit Wasserman 2263e47c249SOrit Wasserman /* 2273e47c249SOrit Wasserman * Real mode guest segments register DPL should be zero. 2283e47c249SOrit Wasserman * Older KVM version were setting it wrongly. 2293e47c249SOrit Wasserman * Fixing it will allow live migration to host with unrestricted guest 2303e47c249SOrit Wasserman * support (otherwise the migration will fail with invalid guest state 2313e47c249SOrit Wasserman * error). 2323e47c249SOrit Wasserman */ 2333e47c249SOrit Wasserman if (!(env->cr[0] & CR0_PE_MASK) && 2343e47c249SOrit Wasserman (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { 2353e47c249SOrit Wasserman env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); 2363e47c249SOrit Wasserman env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); 2373e47c249SOrit Wasserman env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); 2383e47c249SOrit Wasserman env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); 2393e47c249SOrit Wasserman env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); 2403e47c249SOrit Wasserman env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); 2413e47c249SOrit Wasserman } 2423e47c249SOrit Wasserman 243c4c38c8cSJuan Quintela } 244c4c38c8cSJuan Quintela 245468f6581SJuan Quintela static int cpu_post_load(void *opaque, int version_id) 246468f6581SJuan Quintela { 247f56e3a14SAndreas Färber X86CPU *cpu = opaque; 24875a34036SAndreas Färber CPUState *cs = CPU(cpu); 249f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 250468f6581SJuan Quintela int i; 251468f6581SJuan Quintela 25236f96c4bSHaozhong Zhang if (env->tsc_khz && env->user_tsc_khz && 25336f96c4bSHaozhong Zhang env->tsc_khz != env->user_tsc_khz) { 25436f96c4bSHaozhong Zhang error_report("Mismatch between user-specified TSC frequency and " 25536f96c4bSHaozhong Zhang "migrated TSC frequency"); 25636f96c4bSHaozhong Zhang return -EINVAL; 25736f96c4bSHaozhong Zhang } 25836f96c4bSHaozhong Zhang 259*46baa900SDr. David Alan Gilbert if (env->fpregs_format_vmstate) { 260*46baa900SDr. David Alan Gilbert error_report("Unsupported old non-softfloat CPU state"); 261*46baa900SDr. David Alan Gilbert return -EINVAL; 262*46baa900SDr. David Alan Gilbert } 263444ba679SOrit Wasserman /* 264444ba679SOrit Wasserman * Real mode guest segments register DPL should be zero. 265444ba679SOrit Wasserman * Older KVM version were setting it wrongly. 266444ba679SOrit Wasserman * Fixing it will allow live migration from such host that don't have 267444ba679SOrit Wasserman * restricted guest support to a host with unrestricted guest support 268444ba679SOrit Wasserman * (otherwise the migration will fail with invalid guest state 269444ba679SOrit Wasserman * error). 270444ba679SOrit Wasserman */ 271444ba679SOrit Wasserman if (!(env->cr[0] & CR0_PE_MASK) && 272444ba679SOrit Wasserman (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { 273444ba679SOrit Wasserman env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); 274444ba679SOrit Wasserman env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); 275444ba679SOrit Wasserman env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); 276444ba679SOrit Wasserman env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); 277444ba679SOrit Wasserman env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); 278444ba679SOrit Wasserman env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); 279444ba679SOrit Wasserman } 280444ba679SOrit Wasserman 2817125c937SPaolo Bonzini /* Older versions of QEMU incorrectly used CS.DPL as the CPL when 2827125c937SPaolo Bonzini * running under KVM. This is wrong for conforming code segments. 2837125c937SPaolo Bonzini * Luckily, in our implementation the CPL field of hflags is redundant 2847125c937SPaolo Bonzini * and we can get the right value from the SS descriptor privilege level. 2857125c937SPaolo Bonzini */ 2867125c937SPaolo Bonzini env->hflags &= ~HF_CPL_MASK; 2877125c937SPaolo Bonzini env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK; 2887125c937SPaolo Bonzini 289468f6581SJuan Quintela env->fpstt = (env->fpus_vmstate >> 11) & 7; 290468f6581SJuan Quintela env->fpus = env->fpus_vmstate & ~0x3800; 291468f6581SJuan Quintela env->fptag_vmstate ^= 0xff; 292468f6581SJuan Quintela for(i = 0; i < 8; i++) { 293468f6581SJuan Quintela env->fptags[i] = (env->fptag_vmstate >> i) & 1; 294468f6581SJuan Quintela } 2955bde1407SPavel Dovgalyuk update_fp_status(env); 296468f6581SJuan Quintela 297b3310ab3SAndreas Färber cpu_breakpoint_remove_all(cs, BP_CPU); 29875a34036SAndreas Färber cpu_watchpoint_remove_all(cs, BP_CPU); 29993d00d0fSRichard Henderson { 30093d00d0fSRichard Henderson /* Indicate all breakpoints disabled, as they are, then 30193d00d0fSRichard Henderson let the helper re-enable them. */ 30293d00d0fSRichard Henderson target_ulong dr7 = env->dr[7]; 30393d00d0fSRichard Henderson env->dr[7] = dr7 & ~(DR7_GLOBAL_BP_MASK | DR7_LOCAL_BP_MASK); 30493d00d0fSRichard Henderson cpu_x86_update_dr7(env, dr7); 305428065ceSliguang } 306d10eb08fSAlex Bennée tlb_flush(cs); 307428065ceSliguang 308f809c605SPaolo Bonzini if (tcg_enabled()) { 309f809c605SPaolo Bonzini cpu_smm_update(cpu); 310f809c605SPaolo Bonzini } 3111e7fbc6dSJuan Quintela return 0; 312468f6581SJuan Quintela } 313468f6581SJuan Quintela 314f6584ee2SGleb Natapov static bool async_pf_msr_needed(void *opaque) 315f6584ee2SGleb Natapov { 316f56e3a14SAndreas Färber X86CPU *cpu = opaque; 317f6584ee2SGleb Natapov 318f56e3a14SAndreas Färber return cpu->env.async_pf_en_msr != 0; 319f6584ee2SGleb Natapov } 320f6584ee2SGleb Natapov 321bc9a839dSMichael S. Tsirkin static bool pv_eoi_msr_needed(void *opaque) 322bc9a839dSMichael S. Tsirkin { 323f56e3a14SAndreas Färber X86CPU *cpu = opaque; 324bc9a839dSMichael S. Tsirkin 325f56e3a14SAndreas Färber return cpu->env.pv_eoi_en_msr != 0; 326bc9a839dSMichael S. Tsirkin } 327bc9a839dSMichael S. Tsirkin 328917367aaSMarcelo Tosatti static bool steal_time_msr_needed(void *opaque) 329917367aaSMarcelo Tosatti { 3300e503577SMarcelo Tosatti X86CPU *cpu = opaque; 331917367aaSMarcelo Tosatti 3320e503577SMarcelo Tosatti return cpu->env.steal_time_msr != 0; 333917367aaSMarcelo Tosatti } 334917367aaSMarcelo Tosatti 335917367aaSMarcelo Tosatti static const VMStateDescription vmstate_steal_time_msr = { 336917367aaSMarcelo Tosatti .name = "cpu/steal_time_msr", 337917367aaSMarcelo Tosatti .version_id = 1, 338917367aaSMarcelo Tosatti .minimum_version_id = 1, 3395cd8cadaSJuan Quintela .needed = steal_time_msr_needed, 340917367aaSMarcelo Tosatti .fields = (VMStateField[]) { 3410e503577SMarcelo Tosatti VMSTATE_UINT64(env.steal_time_msr, X86CPU), 342917367aaSMarcelo Tosatti VMSTATE_END_OF_LIST() 343917367aaSMarcelo Tosatti } 344917367aaSMarcelo Tosatti }; 345917367aaSMarcelo Tosatti 346f6584ee2SGleb Natapov static const VMStateDescription vmstate_async_pf_msr = { 347f6584ee2SGleb Natapov .name = "cpu/async_pf_msr", 348f6584ee2SGleb Natapov .version_id = 1, 349f6584ee2SGleb Natapov .minimum_version_id = 1, 3505cd8cadaSJuan Quintela .needed = async_pf_msr_needed, 351f6584ee2SGleb Natapov .fields = (VMStateField[]) { 352f56e3a14SAndreas Färber VMSTATE_UINT64(env.async_pf_en_msr, X86CPU), 353f6584ee2SGleb Natapov VMSTATE_END_OF_LIST() 354f6584ee2SGleb Natapov } 355f6584ee2SGleb Natapov }; 356f6584ee2SGleb Natapov 357bc9a839dSMichael S. Tsirkin static const VMStateDescription vmstate_pv_eoi_msr = { 358bc9a839dSMichael S. Tsirkin .name = "cpu/async_pv_eoi_msr", 359bc9a839dSMichael S. Tsirkin .version_id = 1, 360bc9a839dSMichael S. Tsirkin .minimum_version_id = 1, 3615cd8cadaSJuan Quintela .needed = pv_eoi_msr_needed, 362bc9a839dSMichael S. Tsirkin .fields = (VMStateField[]) { 363f56e3a14SAndreas Färber VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU), 364bc9a839dSMichael S. Tsirkin VMSTATE_END_OF_LIST() 365bc9a839dSMichael S. Tsirkin } 366bc9a839dSMichael S. Tsirkin }; 367bc9a839dSMichael S. Tsirkin 36842cc8fa6SJan Kiszka static bool fpop_ip_dp_needed(void *opaque) 36942cc8fa6SJan Kiszka { 370f56e3a14SAndreas Färber X86CPU *cpu = opaque; 371f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 37242cc8fa6SJan Kiszka 37342cc8fa6SJan Kiszka return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0; 37442cc8fa6SJan Kiszka } 37542cc8fa6SJan Kiszka 37642cc8fa6SJan Kiszka static const VMStateDescription vmstate_fpop_ip_dp = { 37742cc8fa6SJan Kiszka .name = "cpu/fpop_ip_dp", 37842cc8fa6SJan Kiszka .version_id = 1, 37942cc8fa6SJan Kiszka .minimum_version_id = 1, 3805cd8cadaSJuan Quintela .needed = fpop_ip_dp_needed, 38142cc8fa6SJan Kiszka .fields = (VMStateField[]) { 382f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpop, X86CPU), 383f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpip, X86CPU), 384f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpdp, X86CPU), 38542cc8fa6SJan Kiszka VMSTATE_END_OF_LIST() 38642cc8fa6SJan Kiszka } 38742cc8fa6SJan Kiszka }; 38842cc8fa6SJan Kiszka 389f28558d3SWill Auld static bool tsc_adjust_needed(void *opaque) 390f28558d3SWill Auld { 391f56e3a14SAndreas Färber X86CPU *cpu = opaque; 392f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 393f28558d3SWill Auld 394f28558d3SWill Auld return env->tsc_adjust != 0; 395f28558d3SWill Auld } 396f28558d3SWill Auld 397f28558d3SWill Auld static const VMStateDescription vmstate_msr_tsc_adjust = { 398f28558d3SWill Auld .name = "cpu/msr_tsc_adjust", 399f28558d3SWill Auld .version_id = 1, 400f28558d3SWill Auld .minimum_version_id = 1, 4015cd8cadaSJuan Quintela .needed = tsc_adjust_needed, 402f28558d3SWill Auld .fields = (VMStateField[]) { 403f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_adjust, X86CPU), 404f28558d3SWill Auld VMSTATE_END_OF_LIST() 405f28558d3SWill Auld } 406f28558d3SWill Auld }; 407f28558d3SWill Auld 408aa82ba54SLiu, Jinsong static bool tscdeadline_needed(void *opaque) 409aa82ba54SLiu, Jinsong { 410f56e3a14SAndreas Färber X86CPU *cpu = opaque; 411f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 412aa82ba54SLiu, Jinsong 413aa82ba54SLiu, Jinsong return env->tsc_deadline != 0; 414aa82ba54SLiu, Jinsong } 415aa82ba54SLiu, Jinsong 416aa82ba54SLiu, Jinsong static const VMStateDescription vmstate_msr_tscdeadline = { 417aa82ba54SLiu, Jinsong .name = "cpu/msr_tscdeadline", 418aa82ba54SLiu, Jinsong .version_id = 1, 419aa82ba54SLiu, Jinsong .minimum_version_id = 1, 4205cd8cadaSJuan Quintela .needed = tscdeadline_needed, 421aa82ba54SLiu, Jinsong .fields = (VMStateField[]) { 422f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_deadline, X86CPU), 423aa82ba54SLiu, Jinsong VMSTATE_END_OF_LIST() 424aa82ba54SLiu, Jinsong } 425aa82ba54SLiu, Jinsong }; 426aa82ba54SLiu, Jinsong 42721e87c46SAvi Kivity static bool misc_enable_needed(void *opaque) 42821e87c46SAvi Kivity { 429f56e3a14SAndreas Färber X86CPU *cpu = opaque; 430f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 43121e87c46SAvi Kivity 43221e87c46SAvi Kivity return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT; 43321e87c46SAvi Kivity } 43421e87c46SAvi Kivity 4350779caebSArthur Chunqi Li static bool feature_control_needed(void *opaque) 4360779caebSArthur Chunqi Li { 4370779caebSArthur Chunqi Li X86CPU *cpu = opaque; 4380779caebSArthur Chunqi Li CPUX86State *env = &cpu->env; 4390779caebSArthur Chunqi Li 4400779caebSArthur Chunqi Li return env->msr_ia32_feature_control != 0; 4410779caebSArthur Chunqi Li } 4420779caebSArthur Chunqi Li 44321e87c46SAvi Kivity static const VMStateDescription vmstate_msr_ia32_misc_enable = { 44421e87c46SAvi Kivity .name = "cpu/msr_ia32_misc_enable", 44521e87c46SAvi Kivity .version_id = 1, 44621e87c46SAvi Kivity .minimum_version_id = 1, 4475cd8cadaSJuan Quintela .needed = misc_enable_needed, 44821e87c46SAvi Kivity .fields = (VMStateField[]) { 449f56e3a14SAndreas Färber VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU), 45021e87c46SAvi Kivity VMSTATE_END_OF_LIST() 45121e87c46SAvi Kivity } 45221e87c46SAvi Kivity }; 45321e87c46SAvi Kivity 4540779caebSArthur Chunqi Li static const VMStateDescription vmstate_msr_ia32_feature_control = { 4550779caebSArthur Chunqi Li .name = "cpu/msr_ia32_feature_control", 4560779caebSArthur Chunqi Li .version_id = 1, 4570779caebSArthur Chunqi Li .minimum_version_id = 1, 4585cd8cadaSJuan Quintela .needed = feature_control_needed, 4590779caebSArthur Chunqi Li .fields = (VMStateField[]) { 4600779caebSArthur Chunqi Li VMSTATE_UINT64(env.msr_ia32_feature_control, X86CPU), 4610779caebSArthur Chunqi Li VMSTATE_END_OF_LIST() 4620779caebSArthur Chunqi Li } 4630779caebSArthur Chunqi Li }; 4640779caebSArthur Chunqi Li 4650d894367SPaolo Bonzini static bool pmu_enable_needed(void *opaque) 4660d894367SPaolo Bonzini { 4670d894367SPaolo Bonzini X86CPU *cpu = opaque; 4680d894367SPaolo Bonzini CPUX86State *env = &cpu->env; 4690d894367SPaolo Bonzini int i; 4700d894367SPaolo Bonzini 4710d894367SPaolo Bonzini if (env->msr_fixed_ctr_ctrl || env->msr_global_ctrl || 4720d894367SPaolo Bonzini env->msr_global_status || env->msr_global_ovf_ctrl) { 4730d894367SPaolo Bonzini return true; 4740d894367SPaolo Bonzini } 4750d894367SPaolo Bonzini for (i = 0; i < MAX_FIXED_COUNTERS; i++) { 4760d894367SPaolo Bonzini if (env->msr_fixed_counters[i]) { 4770d894367SPaolo Bonzini return true; 4780d894367SPaolo Bonzini } 4790d894367SPaolo Bonzini } 4800d894367SPaolo Bonzini for (i = 0; i < MAX_GP_COUNTERS; i++) { 4810d894367SPaolo Bonzini if (env->msr_gp_counters[i] || env->msr_gp_evtsel[i]) { 4820d894367SPaolo Bonzini return true; 4830d894367SPaolo Bonzini } 4840d894367SPaolo Bonzini } 4850d894367SPaolo Bonzini 4860d894367SPaolo Bonzini return false; 4870d894367SPaolo Bonzini } 4880d894367SPaolo Bonzini 4890d894367SPaolo Bonzini static const VMStateDescription vmstate_msr_architectural_pmu = { 4900d894367SPaolo Bonzini .name = "cpu/msr_architectural_pmu", 4910d894367SPaolo Bonzini .version_id = 1, 4920d894367SPaolo Bonzini .minimum_version_id = 1, 4935cd8cadaSJuan Quintela .needed = pmu_enable_needed, 4940d894367SPaolo Bonzini .fields = (VMStateField[]) { 4950d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_fixed_ctr_ctrl, X86CPU), 4960d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ctrl, X86CPU), 4970d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_status, X86CPU), 4980d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ovf_ctrl, X86CPU), 4990d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_fixed_counters, X86CPU, MAX_FIXED_COUNTERS), 5000d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_counters, X86CPU, MAX_GP_COUNTERS), 5010d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_evtsel, X86CPU, MAX_GP_COUNTERS), 5020d894367SPaolo Bonzini VMSTATE_END_OF_LIST() 5030d894367SPaolo Bonzini } 5040d894367SPaolo Bonzini }; 5050d894367SPaolo Bonzini 50679e9ebebSLiu Jinsong static bool mpx_needed(void *opaque) 50779e9ebebSLiu Jinsong { 50879e9ebebSLiu Jinsong X86CPU *cpu = opaque; 50979e9ebebSLiu Jinsong CPUX86State *env = &cpu->env; 51079e9ebebSLiu Jinsong unsigned int i; 51179e9ebebSLiu Jinsong 51279e9ebebSLiu Jinsong for (i = 0; i < 4; i++) { 51379e9ebebSLiu Jinsong if (env->bnd_regs[i].lb || env->bnd_regs[i].ub) { 51479e9ebebSLiu Jinsong return true; 51579e9ebebSLiu Jinsong } 51679e9ebebSLiu Jinsong } 51779e9ebebSLiu Jinsong 51879e9ebebSLiu Jinsong if (env->bndcs_regs.cfgu || env->bndcs_regs.sts) { 51979e9ebebSLiu Jinsong return true; 52079e9ebebSLiu Jinsong } 52179e9ebebSLiu Jinsong 52279e9ebebSLiu Jinsong return !!env->msr_bndcfgs; 52379e9ebebSLiu Jinsong } 52479e9ebebSLiu Jinsong 52579e9ebebSLiu Jinsong static const VMStateDescription vmstate_mpx = { 52679e9ebebSLiu Jinsong .name = "cpu/mpx", 52779e9ebebSLiu Jinsong .version_id = 1, 52879e9ebebSLiu Jinsong .minimum_version_id = 1, 5295cd8cadaSJuan Quintela .needed = mpx_needed, 53079e9ebebSLiu Jinsong .fields = (VMStateField[]) { 53179e9ebebSLiu Jinsong VMSTATE_BND_REGS(env.bnd_regs, X86CPU, 4), 53279e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.cfgu, X86CPU), 53379e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.sts, X86CPU), 53479e9ebebSLiu Jinsong VMSTATE_UINT64(env.msr_bndcfgs, X86CPU), 53579e9ebebSLiu Jinsong VMSTATE_END_OF_LIST() 53679e9ebebSLiu Jinsong } 53779e9ebebSLiu Jinsong }; 53879e9ebebSLiu Jinsong 5391c90ef26SVadim Rozenfeld static bool hyperv_hypercall_enable_needed(void *opaque) 5401c90ef26SVadim Rozenfeld { 5411c90ef26SVadim Rozenfeld X86CPU *cpu = opaque; 5421c90ef26SVadim Rozenfeld CPUX86State *env = &cpu->env; 5431c90ef26SVadim Rozenfeld 5441c90ef26SVadim Rozenfeld return env->msr_hv_hypercall != 0 || env->msr_hv_guest_os_id != 0; 5451c90ef26SVadim Rozenfeld } 5461c90ef26SVadim Rozenfeld 5471c90ef26SVadim Rozenfeld static const VMStateDescription vmstate_msr_hypercall_hypercall = { 5481c90ef26SVadim Rozenfeld .name = "cpu/msr_hyperv_hypercall", 5491c90ef26SVadim Rozenfeld .version_id = 1, 5501c90ef26SVadim Rozenfeld .minimum_version_id = 1, 5515cd8cadaSJuan Quintela .needed = hyperv_hypercall_enable_needed, 5521c90ef26SVadim Rozenfeld .fields = (VMStateField[]) { 5531c90ef26SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_guest_os_id, X86CPU), 554466e6e9dSPaolo Bonzini VMSTATE_UINT64(env.msr_hv_hypercall, X86CPU), 5551c90ef26SVadim Rozenfeld VMSTATE_END_OF_LIST() 5561c90ef26SVadim Rozenfeld } 5571c90ef26SVadim Rozenfeld }; 5581c90ef26SVadim Rozenfeld 5595ef68987SVadim Rozenfeld static bool hyperv_vapic_enable_needed(void *opaque) 5605ef68987SVadim Rozenfeld { 5615ef68987SVadim Rozenfeld X86CPU *cpu = opaque; 5625ef68987SVadim Rozenfeld CPUX86State *env = &cpu->env; 5635ef68987SVadim Rozenfeld 5645ef68987SVadim Rozenfeld return env->msr_hv_vapic != 0; 5655ef68987SVadim Rozenfeld } 5665ef68987SVadim Rozenfeld 5675ef68987SVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_vapic = { 5685ef68987SVadim Rozenfeld .name = "cpu/msr_hyperv_vapic", 5695ef68987SVadim Rozenfeld .version_id = 1, 5705ef68987SVadim Rozenfeld .minimum_version_id = 1, 5715cd8cadaSJuan Quintela .needed = hyperv_vapic_enable_needed, 5725ef68987SVadim Rozenfeld .fields = (VMStateField[]) { 5735ef68987SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_vapic, X86CPU), 5745ef68987SVadim Rozenfeld VMSTATE_END_OF_LIST() 5755ef68987SVadim Rozenfeld } 5765ef68987SVadim Rozenfeld }; 5775ef68987SVadim Rozenfeld 57848a5f3bcSVadim Rozenfeld static bool hyperv_time_enable_needed(void *opaque) 57948a5f3bcSVadim Rozenfeld { 58048a5f3bcSVadim Rozenfeld X86CPU *cpu = opaque; 58148a5f3bcSVadim Rozenfeld CPUX86State *env = &cpu->env; 58248a5f3bcSVadim Rozenfeld 58348a5f3bcSVadim Rozenfeld return env->msr_hv_tsc != 0; 58448a5f3bcSVadim Rozenfeld } 58548a5f3bcSVadim Rozenfeld 58648a5f3bcSVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_time = { 58748a5f3bcSVadim Rozenfeld .name = "cpu/msr_hyperv_time", 58848a5f3bcSVadim Rozenfeld .version_id = 1, 58948a5f3bcSVadim Rozenfeld .minimum_version_id = 1, 5905cd8cadaSJuan Quintela .needed = hyperv_time_enable_needed, 59148a5f3bcSVadim Rozenfeld .fields = (VMStateField[]) { 59248a5f3bcSVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_tsc, X86CPU), 59348a5f3bcSVadim Rozenfeld VMSTATE_END_OF_LIST() 59448a5f3bcSVadim Rozenfeld } 59548a5f3bcSVadim Rozenfeld }; 59648a5f3bcSVadim Rozenfeld 597f2a53c9eSAndrey Smetanin static bool hyperv_crash_enable_needed(void *opaque) 598f2a53c9eSAndrey Smetanin { 599f2a53c9eSAndrey Smetanin X86CPU *cpu = opaque; 600f2a53c9eSAndrey Smetanin CPUX86State *env = &cpu->env; 601f2a53c9eSAndrey Smetanin int i; 602f2a53c9eSAndrey Smetanin 603f2a53c9eSAndrey Smetanin for (i = 0; i < HV_X64_MSR_CRASH_PARAMS; i++) { 604f2a53c9eSAndrey Smetanin if (env->msr_hv_crash_params[i]) { 605f2a53c9eSAndrey Smetanin return true; 606f2a53c9eSAndrey Smetanin } 607f2a53c9eSAndrey Smetanin } 608f2a53c9eSAndrey Smetanin return false; 609f2a53c9eSAndrey Smetanin } 610f2a53c9eSAndrey Smetanin 611f2a53c9eSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_crash = { 612f2a53c9eSAndrey Smetanin .name = "cpu/msr_hyperv_crash", 613f2a53c9eSAndrey Smetanin .version_id = 1, 614f2a53c9eSAndrey Smetanin .minimum_version_id = 1, 615f2a53c9eSAndrey Smetanin .needed = hyperv_crash_enable_needed, 616f2a53c9eSAndrey Smetanin .fields = (VMStateField[]) { 617f2a53c9eSAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_crash_params, 618f2a53c9eSAndrey Smetanin X86CPU, HV_X64_MSR_CRASH_PARAMS), 619f2a53c9eSAndrey Smetanin VMSTATE_END_OF_LIST() 620f2a53c9eSAndrey Smetanin } 621f2a53c9eSAndrey Smetanin }; 622f2a53c9eSAndrey Smetanin 62346eb8f98SAndrey Smetanin static bool hyperv_runtime_enable_needed(void *opaque) 62446eb8f98SAndrey Smetanin { 62546eb8f98SAndrey Smetanin X86CPU *cpu = opaque; 62646eb8f98SAndrey Smetanin CPUX86State *env = &cpu->env; 62746eb8f98SAndrey Smetanin 62851227875SZhuangYanying if (!cpu->hyperv_runtime) { 62951227875SZhuangYanying return false; 63051227875SZhuangYanying } 63151227875SZhuangYanying 63246eb8f98SAndrey Smetanin return env->msr_hv_runtime != 0; 63346eb8f98SAndrey Smetanin } 63446eb8f98SAndrey Smetanin 63546eb8f98SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_runtime = { 63646eb8f98SAndrey Smetanin .name = "cpu/msr_hyperv_runtime", 63746eb8f98SAndrey Smetanin .version_id = 1, 63846eb8f98SAndrey Smetanin .minimum_version_id = 1, 63946eb8f98SAndrey Smetanin .needed = hyperv_runtime_enable_needed, 64046eb8f98SAndrey Smetanin .fields = (VMStateField[]) { 64146eb8f98SAndrey Smetanin VMSTATE_UINT64(env.msr_hv_runtime, X86CPU), 64246eb8f98SAndrey Smetanin VMSTATE_END_OF_LIST() 64346eb8f98SAndrey Smetanin } 64446eb8f98SAndrey Smetanin }; 64546eb8f98SAndrey Smetanin 646866eea9aSAndrey Smetanin static bool hyperv_synic_enable_needed(void *opaque) 647866eea9aSAndrey Smetanin { 648866eea9aSAndrey Smetanin X86CPU *cpu = opaque; 649866eea9aSAndrey Smetanin CPUX86State *env = &cpu->env; 650866eea9aSAndrey Smetanin int i; 651866eea9aSAndrey Smetanin 652866eea9aSAndrey Smetanin if (env->msr_hv_synic_control != 0 || 653866eea9aSAndrey Smetanin env->msr_hv_synic_evt_page != 0 || 654866eea9aSAndrey Smetanin env->msr_hv_synic_msg_page != 0) { 655866eea9aSAndrey Smetanin return true; 656866eea9aSAndrey Smetanin } 657866eea9aSAndrey Smetanin 658866eea9aSAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) { 659866eea9aSAndrey Smetanin if (env->msr_hv_synic_sint[i] != 0) { 660866eea9aSAndrey Smetanin return true; 661866eea9aSAndrey Smetanin } 662866eea9aSAndrey Smetanin } 663866eea9aSAndrey Smetanin 664866eea9aSAndrey Smetanin return false; 665866eea9aSAndrey Smetanin } 666866eea9aSAndrey Smetanin 667866eea9aSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_synic = { 668866eea9aSAndrey Smetanin .name = "cpu/msr_hyperv_synic", 669866eea9aSAndrey Smetanin .version_id = 1, 670866eea9aSAndrey Smetanin .minimum_version_id = 1, 671866eea9aSAndrey Smetanin .needed = hyperv_synic_enable_needed, 672866eea9aSAndrey Smetanin .fields = (VMStateField[]) { 673866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU), 674866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU), 675866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_msg_page, X86CPU), 676866eea9aSAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_synic_sint, X86CPU, 677866eea9aSAndrey Smetanin HV_SYNIC_SINT_COUNT), 678866eea9aSAndrey Smetanin VMSTATE_END_OF_LIST() 679866eea9aSAndrey Smetanin } 680866eea9aSAndrey Smetanin }; 681866eea9aSAndrey Smetanin 682ff99aa64SAndrey Smetanin static bool hyperv_stimer_enable_needed(void *opaque) 683ff99aa64SAndrey Smetanin { 684ff99aa64SAndrey Smetanin X86CPU *cpu = opaque; 685ff99aa64SAndrey Smetanin CPUX86State *env = &cpu->env; 686ff99aa64SAndrey Smetanin int i; 687ff99aa64SAndrey Smetanin 688ff99aa64SAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_stimer_config); i++) { 689ff99aa64SAndrey Smetanin if (env->msr_hv_stimer_config[i] || env->msr_hv_stimer_count[i]) { 690ff99aa64SAndrey Smetanin return true; 691ff99aa64SAndrey Smetanin } 692ff99aa64SAndrey Smetanin } 693ff99aa64SAndrey Smetanin return false; 694ff99aa64SAndrey Smetanin } 695ff99aa64SAndrey Smetanin 696ff99aa64SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_stimer = { 697ff99aa64SAndrey Smetanin .name = "cpu/msr_hyperv_stimer", 698ff99aa64SAndrey Smetanin .version_id = 1, 699ff99aa64SAndrey Smetanin .minimum_version_id = 1, 700ff99aa64SAndrey Smetanin .needed = hyperv_stimer_enable_needed, 701ff99aa64SAndrey Smetanin .fields = (VMStateField[]) { 702ff99aa64SAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_config, 703ff99aa64SAndrey Smetanin X86CPU, HV_SYNIC_STIMER_COUNT), 704ff99aa64SAndrey Smetanin VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_count, 705ff99aa64SAndrey Smetanin X86CPU, HV_SYNIC_STIMER_COUNT), 706ff99aa64SAndrey Smetanin VMSTATE_END_OF_LIST() 707ff99aa64SAndrey Smetanin } 708ff99aa64SAndrey Smetanin }; 709ff99aa64SAndrey Smetanin 7109aecd6f8SChao Peng static bool avx512_needed(void *opaque) 7119aecd6f8SChao Peng { 7129aecd6f8SChao Peng X86CPU *cpu = opaque; 7139aecd6f8SChao Peng CPUX86State *env = &cpu->env; 7149aecd6f8SChao Peng unsigned int i; 7159aecd6f8SChao Peng 7169aecd6f8SChao Peng for (i = 0; i < NB_OPMASK_REGS; i++) { 7179aecd6f8SChao Peng if (env->opmask_regs[i]) { 7189aecd6f8SChao Peng return true; 7199aecd6f8SChao Peng } 7209aecd6f8SChao Peng } 7219aecd6f8SChao Peng 7229aecd6f8SChao Peng for (i = 0; i < CPU_NB_REGS; i++) { 72319cbd87cSEduardo Habkost #define ENV_XMM(reg, field) (env->xmm_regs[reg].ZMM_Q(field)) 724b7711471SPaolo Bonzini if (ENV_XMM(i, 4) || ENV_XMM(i, 6) || 725b7711471SPaolo Bonzini ENV_XMM(i, 5) || ENV_XMM(i, 7)) { 7269aecd6f8SChao Peng return true; 7279aecd6f8SChao Peng } 7289aecd6f8SChao Peng #ifdef TARGET_X86_64 729b7711471SPaolo Bonzini if (ENV_XMM(i+16, 0) || ENV_XMM(i+16, 1) || 730b7711471SPaolo Bonzini ENV_XMM(i+16, 2) || ENV_XMM(i+16, 3) || 731b7711471SPaolo Bonzini ENV_XMM(i+16, 4) || ENV_XMM(i+16, 5) || 732b7711471SPaolo Bonzini ENV_XMM(i+16, 6) || ENV_XMM(i+16, 7)) { 7339aecd6f8SChao Peng return true; 7349aecd6f8SChao Peng } 7359aecd6f8SChao Peng #endif 7369aecd6f8SChao Peng } 7379aecd6f8SChao Peng 7389aecd6f8SChao Peng return false; 7399aecd6f8SChao Peng } 7409aecd6f8SChao Peng 7419aecd6f8SChao Peng static const VMStateDescription vmstate_avx512 = { 7429aecd6f8SChao Peng .name = "cpu/avx512", 7439aecd6f8SChao Peng .version_id = 1, 7449aecd6f8SChao Peng .minimum_version_id = 1, 7455cd8cadaSJuan Quintela .needed = avx512_needed, 7469aecd6f8SChao Peng .fields = (VMStateField[]) { 7479aecd6f8SChao Peng VMSTATE_UINT64_ARRAY(env.opmask_regs, X86CPU, NB_OPMASK_REGS), 748b7711471SPaolo Bonzini VMSTATE_ZMMH_REGS_VARS(env.xmm_regs, X86CPU, 0), 7499aecd6f8SChao Peng #ifdef TARGET_X86_64 750b7711471SPaolo Bonzini VMSTATE_Hi16_ZMM_REGS_VARS(env.xmm_regs, X86CPU, 16), 7519aecd6f8SChao Peng #endif 7529aecd6f8SChao Peng VMSTATE_END_OF_LIST() 7539aecd6f8SChao Peng } 7549aecd6f8SChao Peng }; 7559aecd6f8SChao Peng 75618cd2c17SWanpeng Li static bool xss_needed(void *opaque) 75718cd2c17SWanpeng Li { 75818cd2c17SWanpeng Li X86CPU *cpu = opaque; 75918cd2c17SWanpeng Li CPUX86State *env = &cpu->env; 76018cd2c17SWanpeng Li 76118cd2c17SWanpeng Li return env->xss != 0; 76218cd2c17SWanpeng Li } 76318cd2c17SWanpeng Li 76418cd2c17SWanpeng Li static const VMStateDescription vmstate_xss = { 76518cd2c17SWanpeng Li .name = "cpu/xss", 76618cd2c17SWanpeng Li .version_id = 1, 76718cd2c17SWanpeng Li .minimum_version_id = 1, 7685cd8cadaSJuan Quintela .needed = xss_needed, 76918cd2c17SWanpeng Li .fields = (VMStateField[]) { 77018cd2c17SWanpeng Li VMSTATE_UINT64(env.xss, X86CPU), 77118cd2c17SWanpeng Li VMSTATE_END_OF_LIST() 77218cd2c17SWanpeng Li } 77318cd2c17SWanpeng Li }; 77418cd2c17SWanpeng Li 775f74eefe0SHuaitong Han #ifdef TARGET_X86_64 776f74eefe0SHuaitong Han static bool pkru_needed(void *opaque) 777f74eefe0SHuaitong Han { 778f74eefe0SHuaitong Han X86CPU *cpu = opaque; 779f74eefe0SHuaitong Han CPUX86State *env = &cpu->env; 780f74eefe0SHuaitong Han 781f74eefe0SHuaitong Han return env->pkru != 0; 782f74eefe0SHuaitong Han } 783f74eefe0SHuaitong Han 784f74eefe0SHuaitong Han static const VMStateDescription vmstate_pkru = { 785f74eefe0SHuaitong Han .name = "cpu/pkru", 786f74eefe0SHuaitong Han .version_id = 1, 787f74eefe0SHuaitong Han .minimum_version_id = 1, 788f74eefe0SHuaitong Han .needed = pkru_needed, 789f74eefe0SHuaitong Han .fields = (VMStateField[]){ 790f74eefe0SHuaitong Han VMSTATE_UINT32(env.pkru, X86CPU), 791f74eefe0SHuaitong Han VMSTATE_END_OF_LIST() 792f74eefe0SHuaitong Han } 793f74eefe0SHuaitong Han }; 794f74eefe0SHuaitong Han #endif 795f74eefe0SHuaitong Han 79636f96c4bSHaozhong Zhang static bool tsc_khz_needed(void *opaque) 79736f96c4bSHaozhong Zhang { 79836f96c4bSHaozhong Zhang X86CPU *cpu = opaque; 79936f96c4bSHaozhong Zhang CPUX86State *env = &cpu->env; 80036f96c4bSHaozhong Zhang MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); 80136f96c4bSHaozhong Zhang PCMachineClass *pcmc = PC_MACHINE_CLASS(mc); 80236f96c4bSHaozhong Zhang return env->tsc_khz && pcmc->save_tsc_khz; 80336f96c4bSHaozhong Zhang } 80436f96c4bSHaozhong Zhang 80536f96c4bSHaozhong Zhang static const VMStateDescription vmstate_tsc_khz = { 80636f96c4bSHaozhong Zhang .name = "cpu/tsc_khz", 80736f96c4bSHaozhong Zhang .version_id = 1, 80836f96c4bSHaozhong Zhang .minimum_version_id = 1, 80936f96c4bSHaozhong Zhang .needed = tsc_khz_needed, 81036f96c4bSHaozhong Zhang .fields = (VMStateField[]) { 81136f96c4bSHaozhong Zhang VMSTATE_INT64(env.tsc_khz, X86CPU), 81236f96c4bSHaozhong Zhang VMSTATE_END_OF_LIST() 81336f96c4bSHaozhong Zhang } 81436f96c4bSHaozhong Zhang }; 81536f96c4bSHaozhong Zhang 81687f8b626SAshok Raj static bool mcg_ext_ctl_needed(void *opaque) 81787f8b626SAshok Raj { 81887f8b626SAshok Raj X86CPU *cpu = opaque; 81987f8b626SAshok Raj CPUX86State *env = &cpu->env; 82087f8b626SAshok Raj return cpu->enable_lmce && env->mcg_ext_ctl; 82187f8b626SAshok Raj } 82287f8b626SAshok Raj 82387f8b626SAshok Raj static const VMStateDescription vmstate_mcg_ext_ctl = { 82487f8b626SAshok Raj .name = "cpu/mcg_ext_ctl", 82587f8b626SAshok Raj .version_id = 1, 82687f8b626SAshok Raj .minimum_version_id = 1, 82787f8b626SAshok Raj .needed = mcg_ext_ctl_needed, 82887f8b626SAshok Raj .fields = (VMStateField[]) { 82987f8b626SAshok Raj VMSTATE_UINT64(env.mcg_ext_ctl, X86CPU), 83087f8b626SAshok Raj VMSTATE_END_OF_LIST() 83187f8b626SAshok Raj } 83287f8b626SAshok Raj }; 83387f8b626SAshok Raj 83468bfd0adSMarcelo Tosatti VMStateDescription vmstate_x86_cpu = { 8350cb892aaSJuan Quintela .name = "cpu", 836f56e3a14SAndreas Färber .version_id = 12, 8370cb892aaSJuan Quintela .minimum_version_id = 3, 8380cb892aaSJuan Quintela .pre_save = cpu_pre_save, 8390cb892aaSJuan Quintela .post_load = cpu_post_load, 8400cb892aaSJuan Quintela .fields = (VMStateField[]) { 841f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS), 842f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eip, X86CPU), 843f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eflags, X86CPU), 844f56e3a14SAndreas Färber VMSTATE_UINT32(env.hflags, X86CPU), 8450cb892aaSJuan Quintela /* FPU */ 846f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpuc, X86CPU), 847f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpus_vmstate, X86CPU), 848f56e3a14SAndreas Färber VMSTATE_UINT16(env.fptag_vmstate, X86CPU), 849f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU), 850*46baa900SDr. David Alan Gilbert 851*46baa900SDr. David Alan Gilbert VMSTATE_STRUCT_ARRAY(env.fpregs, X86CPU, 8, 0, vmstate_fpreg, FPReg), 8528dd3dca3Saurel32 853f56e3a14SAndreas Färber VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6), 854f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.ldt, X86CPU), 855f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.tr, X86CPU), 856f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.gdt, X86CPU), 857f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.idt, X86CPU), 858468f6581SJuan Quintela 859f56e3a14SAndreas Färber VMSTATE_UINT32(env.sysenter_cs, X86CPU), 8600cb892aaSJuan Quintela #ifdef TARGET_X86_64 8610cb892aaSJuan Quintela /* Hack: In v7 size changed from 32 to 64 bits on x86_64 */ 862f56e3a14SAndreas Färber VMSTATE_HACK_UINT32(env.sysenter_esp, X86CPU, less_than_7), 863f56e3a14SAndreas Färber VMSTATE_HACK_UINT32(env.sysenter_eip, X86CPU, less_than_7), 864f56e3a14SAndreas Färber VMSTATE_UINTTL_V(env.sysenter_esp, X86CPU, 7), 865f56e3a14SAndreas Färber VMSTATE_UINTTL_V(env.sysenter_eip, X86CPU, 7), 8663c8ce630SJuan Quintela #else 867f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_esp, X86CPU), 868f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_eip, X86CPU), 8693c8ce630SJuan Quintela #endif 8708dd3dca3Saurel32 871f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[0], X86CPU), 872f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[2], X86CPU), 873f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[3], X86CPU), 874f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[4], X86CPU), 875f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8), 8760cb892aaSJuan Quintela /* MMU */ 877f56e3a14SAndreas Färber VMSTATE_INT32(env.a20_mask, X86CPU), 8780cb892aaSJuan Quintela /* XMM */ 879f56e3a14SAndreas Färber VMSTATE_UINT32(env.mxcsr, X86CPU), 880a03c3e90SPaolo Bonzini VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, 0), 8818dd3dca3Saurel32 8828dd3dca3Saurel32 #ifdef TARGET_X86_64 883f56e3a14SAndreas Färber VMSTATE_UINT64(env.efer, X86CPU), 884f56e3a14SAndreas Färber VMSTATE_UINT64(env.star, X86CPU), 885f56e3a14SAndreas Färber VMSTATE_UINT64(env.lstar, X86CPU), 886f56e3a14SAndreas Färber VMSTATE_UINT64(env.cstar, X86CPU), 887f56e3a14SAndreas Färber VMSTATE_UINT64(env.fmask, X86CPU), 888f56e3a14SAndreas Färber VMSTATE_UINT64(env.kernelgsbase, X86CPU), 8898dd3dca3Saurel32 #endif 890f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.smbase, X86CPU, 4), 8918dd3dca3Saurel32 892f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.pat, X86CPU, 5), 893f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.hflags2, X86CPU, 5), 894dd5e3b17Saliguori 895259186a7SAndreas Färber VMSTATE_UINT32_TEST(parent_obj.halted, X86CPU, version_is_5), 896f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.vm_hsave, X86CPU, 5), 897f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.vm_vmcb, X86CPU, 5), 898f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.tsc_offset, X86CPU, 5), 899f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.intercept, X86CPU, 5), 900f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_cr_read, X86CPU, 5), 901f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_cr_write, X86CPU, 5), 902f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_dr_read, X86CPU, 5), 903f56e3a14SAndreas Färber VMSTATE_UINT16_V(env.intercept_dr_write, X86CPU, 5), 904f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.intercept_exceptions, X86CPU, 5), 905f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.v_tpr, X86CPU, 5), 906dd5e3b17Saliguori /* MTRRs */ 907f56e3a14SAndreas Färber VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8), 908f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8), 909d8b5c67bSAlex Williamson VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, MSR_MTRRcap_VCNT, 8), 9100cb892aaSJuan Quintela /* KVM-related states */ 911f56e3a14SAndreas Färber VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9), 912f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.mp_state, X86CPU, 9), 913f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.tsc, X86CPU, 9), 914f56e3a14SAndreas Färber VMSTATE_INT32_V(env.exception_injected, X86CPU, 11), 915f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.soft_interrupt, X86CPU, 11), 916f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.nmi_injected, X86CPU, 11), 917f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.nmi_pending, X86CPU, 11), 918f56e3a14SAndreas Färber VMSTATE_UINT8_V(env.has_error_code, X86CPU, 11), 919f56e3a14SAndreas Färber VMSTATE_UINT32_V(env.sipi_vector, X86CPU, 11), 9200cb892aaSJuan Quintela /* MCE */ 921f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mcg_cap, X86CPU, 10), 922f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mcg_status, X86CPU, 10), 923f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.mcg_ctl, X86CPU, 10), 924f56e3a14SAndreas Färber VMSTATE_UINT64_ARRAY_V(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4, 10), 9250cb892aaSJuan Quintela /* rdtscp */ 926f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.tsc_aux, X86CPU, 11), 9271a03675dSGlauber Costa /* KVM pvclock msr */ 928f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.system_time_msr, X86CPU, 11), 929f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.wall_clock_msr, X86CPU, 11), 930f1665b21SSheng Yang /* XSAVE related fields */ 931f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xcr0, X86CPU, 12), 932f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12), 933b7711471SPaolo Bonzini VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, 0, 12), 9340cb892aaSJuan Quintela VMSTATE_END_OF_LIST() 935a0fb002cSJan Kiszka /* The above list is not sorted /wrt version numbers, watch out! */ 936f6584ee2SGleb Natapov }, 9375cd8cadaSJuan Quintela .subsections = (const VMStateDescription*[]) { 9385cd8cadaSJuan Quintela &vmstate_async_pf_msr, 9395cd8cadaSJuan Quintela &vmstate_pv_eoi_msr, 9405cd8cadaSJuan Quintela &vmstate_steal_time_msr, 9415cd8cadaSJuan Quintela &vmstate_fpop_ip_dp, 9425cd8cadaSJuan Quintela &vmstate_msr_tsc_adjust, 9435cd8cadaSJuan Quintela &vmstate_msr_tscdeadline, 9445cd8cadaSJuan Quintela &vmstate_msr_ia32_misc_enable, 9455cd8cadaSJuan Quintela &vmstate_msr_ia32_feature_control, 9465cd8cadaSJuan Quintela &vmstate_msr_architectural_pmu, 9475cd8cadaSJuan Quintela &vmstate_mpx, 9485cd8cadaSJuan Quintela &vmstate_msr_hypercall_hypercall, 9495cd8cadaSJuan Quintela &vmstate_msr_hyperv_vapic, 9505cd8cadaSJuan Quintela &vmstate_msr_hyperv_time, 951f2a53c9eSAndrey Smetanin &vmstate_msr_hyperv_crash, 95246eb8f98SAndrey Smetanin &vmstate_msr_hyperv_runtime, 953866eea9aSAndrey Smetanin &vmstate_msr_hyperv_synic, 954ff99aa64SAndrey Smetanin &vmstate_msr_hyperv_stimer, 9555cd8cadaSJuan Quintela &vmstate_avx512, 9565cd8cadaSJuan Quintela &vmstate_xss, 95736f96c4bSHaozhong Zhang &vmstate_tsc_khz, 958f74eefe0SHuaitong Han #ifdef TARGET_X86_64 959f74eefe0SHuaitong Han &vmstate_pkru, 960f74eefe0SHuaitong Han #endif 96187f8b626SAshok Raj &vmstate_mcg_ext_ctl, 9625cd8cadaSJuan Quintela NULL 963dd5e3b17Saliguori } 9640cb892aaSJuan Quintela }; 965