1b6a0aa05SPeter Maydell #include "qemu/osdep.h" 233c11879SPaolo Bonzini #include "cpu.h" 3*6ff5da16SPhilippe Mathieu-Daudé #include "exec/cputlb.h" 40d09e41aSPaolo Bonzini #include "hw/isa/isa.h" 51e00b8d5SPaolo Bonzini #include "migration/cpu.h" 6a9dc68d9SClaudio Fontana #include "kvm/hyperv.h" 789a289c7SPaolo Bonzini #include "hw/i386/x86.h" 8a9dc68d9SClaudio Fontana #include "kvm/kvm_i386.h" 9c345104cSJoao Martins #include "hw/xen/xen.h" 108dd3dca3Saurel32 1132cad1ffSPhilippe Mathieu-Daudé #include "system/kvm.h" 1232cad1ffSPhilippe Mathieu-Daudé #include "system/kvm_xen.h" 1332cad1ffSPhilippe Mathieu-Daudé #include "system/tcg.h" 148dd3dca3Saurel32 1536f96c4bSHaozhong Zhang #include "qemu/error-report.h" 1636f96c4bSHaozhong Zhang 1766e6d55bSJuan Quintela static const VMStateDescription vmstate_segment = { 1866e6d55bSJuan Quintela .name = "segment", 1966e6d55bSJuan Quintela .version_id = 1, 2066e6d55bSJuan Quintela .minimum_version_id = 1, 21c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 2266e6d55bSJuan Quintela VMSTATE_UINT32(selector, SegmentCache), 2366e6d55bSJuan Quintela VMSTATE_UINTTL(base, SegmentCache), 2466e6d55bSJuan Quintela VMSTATE_UINT32(limit, SegmentCache), 2566e6d55bSJuan Quintela VMSTATE_UINT32(flags, SegmentCache), 2666e6d55bSJuan Quintela VMSTATE_END_OF_LIST() 2766e6d55bSJuan Quintela } 2866e6d55bSJuan Quintela }; 2966e6d55bSJuan Quintela 300cb892aaSJuan Quintela #define VMSTATE_SEGMENT(_field, _state) { \ 310cb892aaSJuan Quintela .name = (stringify(_field)), \ 320cb892aaSJuan Quintela .size = sizeof(SegmentCache), \ 330cb892aaSJuan Quintela .vmsd = &vmstate_segment, \ 340cb892aaSJuan Quintela .flags = VMS_STRUCT, \ 350cb892aaSJuan Quintela .offset = offsetof(_state, _field) \ 360cb892aaSJuan Quintela + type_check(SegmentCache,typeof_field(_state, _field)) \ 378dd3dca3Saurel32 } 388dd3dca3Saurel32 390cb892aaSJuan Quintela #define VMSTATE_SEGMENT_ARRAY(_field, _state, _n) \ 400cb892aaSJuan Quintela VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_segment, SegmentCache) 418dd3dca3Saurel32 42fc3b0aa2SJuan Quintela static const VMStateDescription vmstate_xmm_reg = { 43fc3b0aa2SJuan Quintela .name = "xmm_reg", 44fc3b0aa2SJuan Quintela .version_id = 1, 45fc3b0aa2SJuan Quintela .minimum_version_id = 1, 46c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 4719cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(0), ZMMReg), 4819cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(1), ZMMReg), 49fc3b0aa2SJuan Quintela VMSTATE_END_OF_LIST() 50fc3b0aa2SJuan Quintela } 51fc3b0aa2SJuan Quintela }; 52fc3b0aa2SJuan Quintela 53a03c3e90SPaolo Bonzini #define VMSTATE_XMM_REGS(_field, _state, _start) \ 54a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 55fa451874SEduardo Habkost vmstate_xmm_reg, ZMMReg) 56fc3b0aa2SJuan Quintela 57b7711471SPaolo Bonzini /* YMMH format is the same as XMM, but for bits 128-255 */ 58f1665b21SSheng Yang static const VMStateDescription vmstate_ymmh_reg = { 59f1665b21SSheng Yang .name = "ymmh_reg", 60f1665b21SSheng Yang .version_id = 1, 61f1665b21SSheng Yang .minimum_version_id = 1, 62c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 6319cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(2), ZMMReg), 6419cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(3), ZMMReg), 65f1665b21SSheng Yang VMSTATE_END_OF_LIST() 66f1665b21SSheng Yang } 67f1665b21SSheng Yang }; 68f1665b21SSheng Yang 69a03c3e90SPaolo Bonzini #define VMSTATE_YMMH_REGS_VARS(_field, _state, _start, _v) \ 70a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, _v, \ 71fa451874SEduardo Habkost vmstate_ymmh_reg, ZMMReg) 72f1665b21SSheng Yang 739aecd6f8SChao Peng static const VMStateDescription vmstate_zmmh_reg = { 749aecd6f8SChao Peng .name = "zmmh_reg", 759aecd6f8SChao Peng .version_id = 1, 769aecd6f8SChao Peng .minimum_version_id = 1, 77c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 7819cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(4), ZMMReg), 7919cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(5), ZMMReg), 8019cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(6), ZMMReg), 8119cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(7), ZMMReg), 829aecd6f8SChao Peng VMSTATE_END_OF_LIST() 839aecd6f8SChao Peng } 849aecd6f8SChao Peng }; 859aecd6f8SChao Peng 86a03c3e90SPaolo Bonzini #define VMSTATE_ZMMH_REGS_VARS(_field, _state, _start) \ 87a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 88fa451874SEduardo Habkost vmstate_zmmh_reg, ZMMReg) 899aecd6f8SChao Peng 909aecd6f8SChao Peng #ifdef TARGET_X86_64 919aecd6f8SChao Peng static const VMStateDescription vmstate_hi16_zmm_reg = { 929aecd6f8SChao Peng .name = "hi16_zmm_reg", 939aecd6f8SChao Peng .version_id = 1, 949aecd6f8SChao Peng .minimum_version_id = 1, 95c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 9619cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(0), ZMMReg), 9719cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(1), ZMMReg), 9819cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(2), ZMMReg), 9919cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(3), ZMMReg), 10019cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(4), ZMMReg), 10119cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(5), ZMMReg), 10219cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(6), ZMMReg), 10319cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(7), ZMMReg), 1049aecd6f8SChao Peng VMSTATE_END_OF_LIST() 1059aecd6f8SChao Peng } 1069aecd6f8SChao Peng }; 1079aecd6f8SChao Peng 108a03c3e90SPaolo Bonzini #define VMSTATE_Hi16_ZMM_REGS_VARS(_field, _state, _start) \ 109a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 110fa451874SEduardo Habkost vmstate_hi16_zmm_reg, ZMMReg) 1119aecd6f8SChao Peng #endif 1129aecd6f8SChao Peng 11379e9ebebSLiu Jinsong static const VMStateDescription vmstate_bnd_regs = { 11479e9ebebSLiu Jinsong .name = "bnd_regs", 11579e9ebebSLiu Jinsong .version_id = 1, 11679e9ebebSLiu Jinsong .minimum_version_id = 1, 117c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 11879e9ebebSLiu Jinsong VMSTATE_UINT64(lb, BNDReg), 11979e9ebebSLiu Jinsong VMSTATE_UINT64(ub, BNDReg), 12079e9ebebSLiu Jinsong VMSTATE_END_OF_LIST() 12179e9ebebSLiu Jinsong } 12279e9ebebSLiu Jinsong }; 12379e9ebebSLiu Jinsong 12479e9ebebSLiu Jinsong #define VMSTATE_BND_REGS(_field, _state, _n) \ 12579e9ebebSLiu Jinsong VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_bnd_regs, BNDReg) 12679e9ebebSLiu Jinsong 127216c07c3SJuan Quintela static const VMStateDescription vmstate_mtrr_var = { 128216c07c3SJuan Quintela .name = "mtrr_var", 129216c07c3SJuan Quintela .version_id = 1, 130216c07c3SJuan Quintela .minimum_version_id = 1, 131c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 132216c07c3SJuan Quintela VMSTATE_UINT64(base, MTRRVar), 133216c07c3SJuan Quintela VMSTATE_UINT64(mask, MTRRVar), 134216c07c3SJuan Quintela VMSTATE_END_OF_LIST() 135216c07c3SJuan Quintela } 136216c07c3SJuan Quintela }; 137216c07c3SJuan Quintela 1380cb892aaSJuan Quintela #define VMSTATE_MTRR_VARS(_field, _state, _n, _v) \ 1390cb892aaSJuan Quintela VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar) 140216c07c3SJuan Quintela 141f2e7c2fcSYang Weijiang static const VMStateDescription vmstate_lbr_records_var = { 142f2e7c2fcSYang Weijiang .name = "lbr_records_var", 143f2e7c2fcSYang Weijiang .version_id = 1, 144f2e7c2fcSYang Weijiang .minimum_version_id = 1, 145c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 146f2e7c2fcSYang Weijiang VMSTATE_UINT64(from, LBREntry), 147f2e7c2fcSYang Weijiang VMSTATE_UINT64(to, LBREntry), 148f2e7c2fcSYang Weijiang VMSTATE_UINT64(info, LBREntry), 149f2e7c2fcSYang Weijiang VMSTATE_END_OF_LIST() 150f2e7c2fcSYang Weijiang } 151f2e7c2fcSYang Weijiang }; 152f2e7c2fcSYang Weijiang 153f2e7c2fcSYang Weijiang #define VMSTATE_LBR_VARS(_field, _state, _n, _v) \ 154f2e7c2fcSYang Weijiang VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_lbr_records_var, \ 155f2e7c2fcSYang Weijiang LBREntry) 156f2e7c2fcSYang Weijiang 157ab808276SDr. David Alan Gilbert typedef struct x86_FPReg_tmp { 158ab808276SDr. David Alan Gilbert FPReg *parent; 159ab808276SDr. David Alan Gilbert uint64_t tmp_mant; 160ab808276SDr. David Alan Gilbert uint16_t tmp_exp; 161ab808276SDr. David Alan Gilbert } x86_FPReg_tmp; 1623c8ce630SJuan Quintela 163db573d2cSYang Zhong static void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f) 164db573d2cSYang Zhong { 165db573d2cSYang Zhong CPU_LDoubleU temp; 166db573d2cSYang Zhong 167db573d2cSYang Zhong temp.d = f; 168db573d2cSYang Zhong *pmant = temp.l.lower; 169db573d2cSYang Zhong *pexp = temp.l.upper; 170db573d2cSYang Zhong } 171db573d2cSYang Zhong 172db573d2cSYang Zhong static floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper) 173db573d2cSYang Zhong { 174db573d2cSYang Zhong CPU_LDoubleU temp; 175db573d2cSYang Zhong 176db573d2cSYang Zhong temp.l.upper = upper; 177db573d2cSYang Zhong temp.l.lower = mant; 178db573d2cSYang Zhong return temp.d; 179db573d2cSYang Zhong } 180db573d2cSYang Zhong 18144b1ff31SDr. David Alan Gilbert static int fpreg_pre_save(void *opaque) 1823c8ce630SJuan Quintela { 183ab808276SDr. David Alan Gilbert x86_FPReg_tmp *tmp = opaque; 184ab808276SDr. David Alan Gilbert 1853c8ce630SJuan Quintela /* we save the real CPU data (in case of MMX usage only 'mant' 1863c8ce630SJuan Quintela contains the MMX register */ 187ab808276SDr. David Alan Gilbert cpu_get_fp80(&tmp->tmp_mant, &tmp->tmp_exp, tmp->parent->d); 18844b1ff31SDr. David Alan Gilbert 18944b1ff31SDr. David Alan Gilbert return 0; 190ab808276SDr. David Alan Gilbert } 1912c21ee76SJianjun Duan 192ab808276SDr. David Alan Gilbert static int fpreg_post_load(void *opaque, int version) 193ab808276SDr. David Alan Gilbert { 194ab808276SDr. David Alan Gilbert x86_FPReg_tmp *tmp = opaque; 195ab808276SDr. David Alan Gilbert 196ab808276SDr. David Alan Gilbert tmp->parent->d = cpu_set_fp80(tmp->tmp_mant, tmp->tmp_exp); 1972c21ee76SJianjun Duan return 0; 1983c8ce630SJuan Quintela } 1993c8ce630SJuan Quintela 200ab808276SDr. David Alan Gilbert static const VMStateDescription vmstate_fpreg_tmp = { 201ab808276SDr. David Alan Gilbert .name = "fpreg_tmp", 202ab808276SDr. David Alan Gilbert .post_load = fpreg_post_load, 203ab808276SDr. David Alan Gilbert .pre_save = fpreg_pre_save, 204c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 205ab808276SDr. David Alan Gilbert VMSTATE_UINT64(tmp_mant, x86_FPReg_tmp), 206ab808276SDr. David Alan Gilbert VMSTATE_UINT16(tmp_exp, x86_FPReg_tmp), 207ab808276SDr. David Alan Gilbert VMSTATE_END_OF_LIST() 208ab808276SDr. David Alan Gilbert } 209ab808276SDr. David Alan Gilbert }; 210ab808276SDr. David Alan Gilbert 211ab808276SDr. David Alan Gilbert static const VMStateDescription vmstate_fpreg = { 2120cb892aaSJuan Quintela .name = "fpreg", 213c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 214ab808276SDr. David Alan Gilbert VMSTATE_WITH_TMP(FPReg, x86_FPReg_tmp, vmstate_fpreg_tmp), 215ab808276SDr. David Alan Gilbert VMSTATE_END_OF_LIST() 216ab808276SDr. David Alan Gilbert } 2170cb892aaSJuan Quintela }; 2180cb892aaSJuan Quintela 21944b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque) 2208dd3dca3Saurel32 { 221f56e3a14SAndreas Färber X86CPU *cpu = opaque; 222f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 2230e607a80SJan Kiszka int i; 224e3126a5cSLara Lazier env->v_tpr = env->int_ctl & V_TPR_MASK; 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 251ebbfef2fSLiran Alon #ifdef CONFIG_KVM 25279a197abSLiran Alon /* 25379a197abSLiran Alon * In case vCPU may have enabled VMX, we need to make sure kernel have 25479a197abSLiran Alon * required capabilities in order to perform migration correctly: 25579a197abSLiran Alon * 25679a197abSLiran Alon * 1) We must be able to extract vCPU nested-state from KVM. 25779a197abSLiran Alon * 25879a197abSLiran Alon * 2) In case vCPU is running in guest-mode and it has a pending exception, 25979a197abSLiran Alon * we must be able to determine if it's in a pending or injected state. 26079a197abSLiran Alon * Note that in case KVM don't have required capability to do so, 26179a197abSLiran Alon * a pending/injected exception will always appear as an 26279a197abSLiran Alon * injected exception. 26379a197abSLiran Alon */ 26479a197abSLiran Alon if (kvm_enabled() && cpu_vmx_maybe_enabled(env) && 26579a197abSLiran Alon (!env->nested_state || 26679a197abSLiran Alon (!kvm_has_exception_payload() && (env->hflags & HF_GUEST_MASK) && 26779a197abSLiran Alon env->exception_injected))) { 26879a197abSLiran Alon error_report("Guest maybe enabled nested virtualization but kernel " 26979a197abSLiran Alon "does not support required capabilities to save vCPU " 27079a197abSLiran Alon "nested state"); 271ebbfef2fSLiran Alon return -EINVAL; 272ebbfef2fSLiran Alon } 273ebbfef2fSLiran Alon #endif 274ebbfef2fSLiran Alon 275fd13f23bSLiran Alon /* 276fd13f23bSLiran Alon * When vCPU is running L2 and exception is still pending, 277fd13f23bSLiran Alon * it can potentially be intercepted by L1 hypervisor. 278fd13f23bSLiran Alon * In contrast to an injected exception which cannot be 279fd13f23bSLiran Alon * intercepted anymore. 280fd13f23bSLiran Alon * 281fd13f23bSLiran Alon * Furthermore, when a L2 exception is intercepted by L1 2827332a4a4SCameron Esfahani * hypervisor, its exception payload (CR2/DR6 on #PF/#DB) 283fd13f23bSLiran Alon * should not be set yet in the respective vCPU register. 284fd13f23bSLiran Alon * Thus, in case an exception is pending, it is 285bad5cfcdSMichael Tokarev * important to save the exception payload separately. 286fd13f23bSLiran Alon * 287fd13f23bSLiran Alon * Therefore, if an exception is not in a pending state 288fd13f23bSLiran Alon * or vCPU is not in guest-mode, it is not important to 289fd13f23bSLiran Alon * distinguish between a pending and injected exception 290bad5cfcdSMichael Tokarev * and we don't need to store separately the exception payload. 291fd13f23bSLiran Alon * 2927332a4a4SCameron Esfahani * In order to preserve better backwards-compatible migration, 293fd13f23bSLiran Alon * convert a pending exception to an injected exception in 2947332a4a4SCameron Esfahani * case it is not important to distinguish between them 295fd13f23bSLiran Alon * as described above. 296fd13f23bSLiran Alon */ 297fd13f23bSLiran Alon if (env->exception_pending && !(env->hflags & HF_GUEST_MASK)) { 298fd13f23bSLiran Alon env->exception_pending = 0; 299fd13f23bSLiran Alon env->exception_injected = 1; 300fd13f23bSLiran Alon 301fd13f23bSLiran Alon if (env->exception_has_payload) { 302fd13f23bSLiran Alon if (env->exception_nr == EXCP01_DB) { 303fd13f23bSLiran Alon env->dr[6] = env->exception_payload; 304fd13f23bSLiran Alon } else if (env->exception_nr == EXCP0E_PAGE) { 305fd13f23bSLiran Alon env->cr[2] = env->exception_payload; 306fd13f23bSLiran Alon } 307fd13f23bSLiran Alon } 308fd13f23bSLiran Alon } 309fd13f23bSLiran Alon 31044b1ff31SDr. David Alan Gilbert return 0; 311c4c38c8cSJuan Quintela } 312c4c38c8cSJuan Quintela 313468f6581SJuan Quintela static int cpu_post_load(void *opaque, int version_id) 314468f6581SJuan Quintela { 315f56e3a14SAndreas Färber X86CPU *cpu = opaque; 31675a34036SAndreas Färber CPUState *cs = CPU(cpu); 317f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 318468f6581SJuan Quintela int i; 319468f6581SJuan Quintela 32036f96c4bSHaozhong Zhang if (env->tsc_khz && env->user_tsc_khz && 32136f96c4bSHaozhong Zhang env->tsc_khz != env->user_tsc_khz) { 32236f96c4bSHaozhong Zhang error_report("Mismatch between user-specified TSC frequency and " 32336f96c4bSHaozhong Zhang "migrated TSC frequency"); 32436f96c4bSHaozhong Zhang return -EINVAL; 32536f96c4bSHaozhong Zhang } 32636f96c4bSHaozhong Zhang 32746baa900SDr. David Alan Gilbert if (env->fpregs_format_vmstate) { 32846baa900SDr. David Alan Gilbert error_report("Unsupported old non-softfloat CPU state"); 32946baa900SDr. David Alan Gilbert return -EINVAL; 33046baa900SDr. David Alan Gilbert } 331444ba679SOrit Wasserman /* 332444ba679SOrit Wasserman * Real mode guest segments register DPL should be zero. 333444ba679SOrit Wasserman * Older KVM version were setting it wrongly. 334444ba679SOrit Wasserman * Fixing it will allow live migration from such host that don't have 335444ba679SOrit Wasserman * restricted guest support to a host with unrestricted guest support 336444ba679SOrit Wasserman * (otherwise the migration will fail with invalid guest state 337444ba679SOrit Wasserman * error). 338444ba679SOrit Wasserman */ 339444ba679SOrit Wasserman if (!(env->cr[0] & CR0_PE_MASK) && 340444ba679SOrit Wasserman (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { 341444ba679SOrit Wasserman env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); 342444ba679SOrit Wasserman env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); 343444ba679SOrit Wasserman env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); 344444ba679SOrit Wasserman env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); 345444ba679SOrit Wasserman env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); 346444ba679SOrit Wasserman env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); 347444ba679SOrit Wasserman } 348444ba679SOrit Wasserman 3497125c937SPaolo Bonzini /* Older versions of QEMU incorrectly used CS.DPL as the CPL when 3507125c937SPaolo Bonzini * running under KVM. This is wrong for conforming code segments. 3517125c937SPaolo Bonzini * Luckily, in our implementation the CPL field of hflags is redundant 3527125c937SPaolo Bonzini * and we can get the right value from the SS descriptor privilege level. 3537125c937SPaolo Bonzini */ 3547125c937SPaolo Bonzini env->hflags &= ~HF_CPL_MASK; 3557125c937SPaolo Bonzini env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK; 3567125c937SPaolo Bonzini 357ebbfef2fSLiran Alon #ifdef CONFIG_KVM 358ebbfef2fSLiran Alon if ((env->hflags & HF_GUEST_MASK) && 359ebbfef2fSLiran Alon (!env->nested_state || 360ebbfef2fSLiran Alon !(env->nested_state->flags & KVM_STATE_NESTED_GUEST_MODE))) { 361ebbfef2fSLiran Alon error_report("vCPU set in guest-mode inconsistent with " 362ebbfef2fSLiran Alon "migrated kernel nested state"); 363ebbfef2fSLiran Alon return -EINVAL; 364ebbfef2fSLiran Alon } 365ebbfef2fSLiran Alon #endif 366ebbfef2fSLiran Alon 367fd13f23bSLiran Alon /* 368fd13f23bSLiran Alon * There are cases that we can get valid exception_nr with both 369fd13f23bSLiran Alon * exception_pending and exception_injected being cleared. 370fd13f23bSLiran Alon * This can happen in one of the following scenarios: 371fd13f23bSLiran Alon * 1) Source is older QEMU without KVM_CAP_EXCEPTION_PAYLOAD support. 372fd13f23bSLiran Alon * 2) Source is running on kernel without KVM_CAP_EXCEPTION_PAYLOAD support. 373fd13f23bSLiran Alon * 3) "cpu/exception_info" subsection not sent because there is no exception 374fd13f23bSLiran Alon * pending or guest wasn't running L2 (See comment in cpu_pre_save()). 375fd13f23bSLiran Alon * 376fd13f23bSLiran Alon * In those cases, we can just deduce that a valid exception_nr means 377fd13f23bSLiran Alon * we can treat the exception as already injected. 378fd13f23bSLiran Alon */ 379fd13f23bSLiran Alon if ((env->exception_nr != -1) && 380fd13f23bSLiran Alon !env->exception_pending && !env->exception_injected) { 381fd13f23bSLiran Alon env->exception_injected = 1; 382fd13f23bSLiran Alon } 383fd13f23bSLiran Alon 384468f6581SJuan Quintela env->fpstt = (env->fpus_vmstate >> 11) & 7; 385468f6581SJuan Quintela env->fpus = env->fpus_vmstate & ~0x3800; 386468f6581SJuan Quintela env->fptag_vmstate ^= 0xff; 387468f6581SJuan Quintela for(i = 0; i < 8; i++) { 388468f6581SJuan Quintela env->fptags[i] = (env->fptag_vmstate >> i) & 1; 389468f6581SJuan Quintela } 3901d8ad165SYang Zhong if (tcg_enabled()) { 39179c664f6SYang Zhong target_ulong dr7; 3925bde1407SPavel Dovgalyuk update_fp_status(env); 3931d8ad165SYang Zhong update_mxcsr_status(env); 394468f6581SJuan Quintela 395b3310ab3SAndreas Färber cpu_breakpoint_remove_all(cs, BP_CPU); 39675a34036SAndreas Färber cpu_watchpoint_remove_all(cs, BP_CPU); 39779c664f6SYang Zhong 39893d00d0fSRichard Henderson /* Indicate all breakpoints disabled, as they are, then 39993d00d0fSRichard Henderson let the helper re-enable them. */ 40079c664f6SYang Zhong dr7 = env->dr[7]; 40193d00d0fSRichard Henderson env->dr[7] = dr7 & ~(DR7_GLOBAL_BP_MASK | DR7_LOCAL_BP_MASK); 40293d00d0fSRichard Henderson cpu_x86_update_dr7(env, dr7); 403428065ceSliguang } 404d10eb08fSAlex Bennée tlb_flush(cs); 4051e7fbc6dSJuan Quintela return 0; 406468f6581SJuan Quintela } 407468f6581SJuan Quintela 408f6584ee2SGleb Natapov static bool async_pf_msr_needed(void *opaque) 409f6584ee2SGleb Natapov { 410f56e3a14SAndreas Färber X86CPU *cpu = opaque; 411f6584ee2SGleb Natapov 412f56e3a14SAndreas Färber return cpu->env.async_pf_en_msr != 0; 413f6584ee2SGleb Natapov } 414f6584ee2SGleb Natapov 415db5daafaSVitaly Kuznetsov static bool async_pf_int_msr_needed(void *opaque) 416db5daafaSVitaly Kuznetsov { 417db5daafaSVitaly Kuznetsov X86CPU *cpu = opaque; 418db5daafaSVitaly Kuznetsov 419db5daafaSVitaly Kuznetsov return cpu->env.async_pf_int_msr != 0; 420db5daafaSVitaly Kuznetsov } 421db5daafaSVitaly Kuznetsov 422bc9a839dSMichael S. Tsirkin static bool pv_eoi_msr_needed(void *opaque) 423bc9a839dSMichael S. Tsirkin { 424f56e3a14SAndreas Färber X86CPU *cpu = opaque; 425bc9a839dSMichael S. Tsirkin 426f56e3a14SAndreas Färber return cpu->env.pv_eoi_en_msr != 0; 427bc9a839dSMichael S. Tsirkin } 428bc9a839dSMichael S. Tsirkin 429917367aaSMarcelo Tosatti static bool steal_time_msr_needed(void *opaque) 430917367aaSMarcelo Tosatti { 4310e503577SMarcelo Tosatti X86CPU *cpu = opaque; 432917367aaSMarcelo Tosatti 4330e503577SMarcelo Tosatti return cpu->env.steal_time_msr != 0; 434917367aaSMarcelo Tosatti } 435917367aaSMarcelo Tosatti 436fd13f23bSLiran Alon static bool exception_info_needed(void *opaque) 437fd13f23bSLiran Alon { 438fd13f23bSLiran Alon X86CPU *cpu = opaque; 439fd13f23bSLiran Alon CPUX86State *env = &cpu->env; 440fd13f23bSLiran Alon 441fd13f23bSLiran Alon /* 442fd13f23bSLiran Alon * It is important to save exception-info only in case 4437332a4a4SCameron Esfahani * we need to distinguish between a pending and injected 444fd13f23bSLiran Alon * exception. Which is only required in case there is a 445fd13f23bSLiran Alon * pending exception and vCPU is running L2. 446fd13f23bSLiran Alon * For more info, refer to comment in cpu_pre_save(). 447fd13f23bSLiran Alon */ 448fd13f23bSLiran Alon return env->exception_pending && (env->hflags & HF_GUEST_MASK); 449fd13f23bSLiran Alon } 450fd13f23bSLiran Alon 451fd13f23bSLiran Alon static const VMStateDescription vmstate_exception_info = { 452fd13f23bSLiran Alon .name = "cpu/exception_info", 453fd13f23bSLiran Alon .version_id = 1, 454fd13f23bSLiran Alon .minimum_version_id = 1, 455fd13f23bSLiran Alon .needed = exception_info_needed, 456c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 457fd13f23bSLiran Alon VMSTATE_UINT8(env.exception_pending, X86CPU), 458fd13f23bSLiran Alon VMSTATE_UINT8(env.exception_injected, X86CPU), 459fd13f23bSLiran Alon VMSTATE_UINT8(env.exception_has_payload, X86CPU), 460fd13f23bSLiran Alon VMSTATE_UINT64(env.exception_payload, X86CPU), 461fd13f23bSLiran Alon VMSTATE_END_OF_LIST() 462fd13f23bSLiran Alon } 463fd13f23bSLiran Alon }; 464fd13f23bSLiran Alon 465d645e132SMarcelo Tosatti /* Poll control MSR enabled by default */ 466d645e132SMarcelo Tosatti static bool poll_control_msr_needed(void *opaque) 467d645e132SMarcelo Tosatti { 468d645e132SMarcelo Tosatti X86CPU *cpu = opaque; 469d645e132SMarcelo Tosatti 470d645e132SMarcelo Tosatti return cpu->env.poll_control_msr != 1; 471d645e132SMarcelo Tosatti } 472d645e132SMarcelo Tosatti 473917367aaSMarcelo Tosatti static const VMStateDescription vmstate_steal_time_msr = { 474917367aaSMarcelo Tosatti .name = "cpu/steal_time_msr", 475917367aaSMarcelo Tosatti .version_id = 1, 476917367aaSMarcelo Tosatti .minimum_version_id = 1, 4775cd8cadaSJuan Quintela .needed = steal_time_msr_needed, 478c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 4790e503577SMarcelo Tosatti VMSTATE_UINT64(env.steal_time_msr, X86CPU), 480917367aaSMarcelo Tosatti VMSTATE_END_OF_LIST() 481917367aaSMarcelo Tosatti } 482917367aaSMarcelo Tosatti }; 483917367aaSMarcelo Tosatti 484f6584ee2SGleb Natapov static const VMStateDescription vmstate_async_pf_msr = { 485f6584ee2SGleb Natapov .name = "cpu/async_pf_msr", 486f6584ee2SGleb Natapov .version_id = 1, 487f6584ee2SGleb Natapov .minimum_version_id = 1, 4885cd8cadaSJuan Quintela .needed = async_pf_msr_needed, 489c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 490f56e3a14SAndreas Färber VMSTATE_UINT64(env.async_pf_en_msr, X86CPU), 491f6584ee2SGleb Natapov VMSTATE_END_OF_LIST() 492f6584ee2SGleb Natapov } 493f6584ee2SGleb Natapov }; 494f6584ee2SGleb Natapov 495db5daafaSVitaly Kuznetsov static const VMStateDescription vmstate_async_pf_int_msr = { 496db5daafaSVitaly Kuznetsov .name = "cpu/async_pf_int_msr", 497db5daafaSVitaly Kuznetsov .version_id = 1, 498db5daafaSVitaly Kuznetsov .minimum_version_id = 1, 499db5daafaSVitaly Kuznetsov .needed = async_pf_int_msr_needed, 500c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 501db5daafaSVitaly Kuznetsov VMSTATE_UINT64(env.async_pf_int_msr, X86CPU), 502db5daafaSVitaly Kuznetsov VMSTATE_END_OF_LIST() 503db5daafaSVitaly Kuznetsov } 504db5daafaSVitaly Kuznetsov }; 505db5daafaSVitaly Kuznetsov 506bc9a839dSMichael S. Tsirkin static const VMStateDescription vmstate_pv_eoi_msr = { 507bc9a839dSMichael S. Tsirkin .name = "cpu/async_pv_eoi_msr", 508bc9a839dSMichael S. Tsirkin .version_id = 1, 509bc9a839dSMichael S. Tsirkin .minimum_version_id = 1, 5105cd8cadaSJuan Quintela .needed = pv_eoi_msr_needed, 511c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 512f56e3a14SAndreas Färber VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU), 513bc9a839dSMichael S. Tsirkin VMSTATE_END_OF_LIST() 514bc9a839dSMichael S. Tsirkin } 515bc9a839dSMichael S. Tsirkin }; 516bc9a839dSMichael S. Tsirkin 517d645e132SMarcelo Tosatti static const VMStateDescription vmstate_poll_control_msr = { 518d645e132SMarcelo Tosatti .name = "cpu/poll_control_msr", 519d645e132SMarcelo Tosatti .version_id = 1, 520d645e132SMarcelo Tosatti .minimum_version_id = 1, 521d645e132SMarcelo Tosatti .needed = poll_control_msr_needed, 522c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 523d645e132SMarcelo Tosatti VMSTATE_UINT64(env.poll_control_msr, X86CPU), 524d645e132SMarcelo Tosatti VMSTATE_END_OF_LIST() 525d645e132SMarcelo Tosatti } 526d645e132SMarcelo Tosatti }; 527d645e132SMarcelo Tosatti 52842cc8fa6SJan Kiszka static bool fpop_ip_dp_needed(void *opaque) 52942cc8fa6SJan Kiszka { 530f56e3a14SAndreas Färber X86CPU *cpu = opaque; 531f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 53242cc8fa6SJan Kiszka 53342cc8fa6SJan Kiszka return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0; 53442cc8fa6SJan Kiszka } 53542cc8fa6SJan Kiszka 53642cc8fa6SJan Kiszka static const VMStateDescription vmstate_fpop_ip_dp = { 53742cc8fa6SJan Kiszka .name = "cpu/fpop_ip_dp", 53842cc8fa6SJan Kiszka .version_id = 1, 53942cc8fa6SJan Kiszka .minimum_version_id = 1, 5405cd8cadaSJuan Quintela .needed = fpop_ip_dp_needed, 541c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 542f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpop, X86CPU), 543f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpip, X86CPU), 544f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpdp, X86CPU), 54542cc8fa6SJan Kiszka VMSTATE_END_OF_LIST() 54642cc8fa6SJan Kiszka } 54742cc8fa6SJan Kiszka }; 54842cc8fa6SJan Kiszka 549f28558d3SWill Auld static bool tsc_adjust_needed(void *opaque) 550f28558d3SWill Auld { 551f56e3a14SAndreas Färber X86CPU *cpu = opaque; 552f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 553f28558d3SWill Auld 554f28558d3SWill Auld return env->tsc_adjust != 0; 555f28558d3SWill Auld } 556f28558d3SWill Auld 557f28558d3SWill Auld static const VMStateDescription vmstate_msr_tsc_adjust = { 558f28558d3SWill Auld .name = "cpu/msr_tsc_adjust", 559f28558d3SWill Auld .version_id = 1, 560f28558d3SWill Auld .minimum_version_id = 1, 5615cd8cadaSJuan Quintela .needed = tsc_adjust_needed, 562c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 563f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_adjust, X86CPU), 564f28558d3SWill Auld VMSTATE_END_OF_LIST() 565f28558d3SWill Auld } 566f28558d3SWill Auld }; 567f28558d3SWill Auld 568e13713dbSLiran Alon static bool msr_smi_count_needed(void *opaque) 569e13713dbSLiran Alon { 570e13713dbSLiran Alon X86CPU *cpu = opaque; 571e13713dbSLiran Alon CPUX86State *env = &cpu->env; 572e13713dbSLiran Alon 573990e0be2SPaolo Bonzini return cpu->migrate_smi_count && env->msr_smi_count != 0; 574e13713dbSLiran Alon } 575e13713dbSLiran Alon 576e13713dbSLiran Alon static const VMStateDescription vmstate_msr_smi_count = { 577e13713dbSLiran Alon .name = "cpu/msr_smi_count", 578e13713dbSLiran Alon .version_id = 1, 579e13713dbSLiran Alon .minimum_version_id = 1, 580e13713dbSLiran Alon .needed = msr_smi_count_needed, 581c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 582e13713dbSLiran Alon VMSTATE_UINT64(env.msr_smi_count, X86CPU), 583e13713dbSLiran Alon VMSTATE_END_OF_LIST() 584e13713dbSLiran Alon } 585e13713dbSLiran Alon }; 586e13713dbSLiran Alon 587aa82ba54SLiu, Jinsong static bool tscdeadline_needed(void *opaque) 588aa82ba54SLiu, Jinsong { 589f56e3a14SAndreas Färber X86CPU *cpu = opaque; 590f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 591aa82ba54SLiu, Jinsong 592aa82ba54SLiu, Jinsong return env->tsc_deadline != 0; 593aa82ba54SLiu, Jinsong } 594aa82ba54SLiu, Jinsong 595aa82ba54SLiu, Jinsong static const VMStateDescription vmstate_msr_tscdeadline = { 596aa82ba54SLiu, Jinsong .name = "cpu/msr_tscdeadline", 597aa82ba54SLiu, Jinsong .version_id = 1, 598aa82ba54SLiu, Jinsong .minimum_version_id = 1, 5995cd8cadaSJuan Quintela .needed = tscdeadline_needed, 600c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 601f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_deadline, X86CPU), 602aa82ba54SLiu, Jinsong VMSTATE_END_OF_LIST() 603aa82ba54SLiu, Jinsong } 604aa82ba54SLiu, Jinsong }; 605aa82ba54SLiu, Jinsong 60621e87c46SAvi Kivity static bool misc_enable_needed(void *opaque) 60721e87c46SAvi Kivity { 608f56e3a14SAndreas Färber X86CPU *cpu = opaque; 609f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 61021e87c46SAvi Kivity 61121e87c46SAvi Kivity return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT; 61221e87c46SAvi Kivity } 61321e87c46SAvi Kivity 6140779caebSArthur Chunqi Li static bool feature_control_needed(void *opaque) 6150779caebSArthur Chunqi Li { 6160779caebSArthur Chunqi Li X86CPU *cpu = opaque; 6170779caebSArthur Chunqi Li CPUX86State *env = &cpu->env; 6180779caebSArthur Chunqi Li 6190779caebSArthur Chunqi Li return env->msr_ia32_feature_control != 0; 6200779caebSArthur Chunqi Li } 6210779caebSArthur Chunqi Li 62221e87c46SAvi Kivity static const VMStateDescription vmstate_msr_ia32_misc_enable = { 62321e87c46SAvi Kivity .name = "cpu/msr_ia32_misc_enable", 62421e87c46SAvi Kivity .version_id = 1, 62521e87c46SAvi Kivity .minimum_version_id = 1, 6265cd8cadaSJuan Quintela .needed = misc_enable_needed, 627c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 628f56e3a14SAndreas Färber VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU), 62921e87c46SAvi Kivity VMSTATE_END_OF_LIST() 63021e87c46SAvi Kivity } 63121e87c46SAvi Kivity }; 63221e87c46SAvi Kivity 6330779caebSArthur Chunqi Li static const VMStateDescription vmstate_msr_ia32_feature_control = { 6340779caebSArthur Chunqi Li .name = "cpu/msr_ia32_feature_control", 6350779caebSArthur Chunqi Li .version_id = 1, 6360779caebSArthur Chunqi Li .minimum_version_id = 1, 6375cd8cadaSJuan Quintela .needed = feature_control_needed, 638c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 6390779caebSArthur Chunqi Li VMSTATE_UINT64(env.msr_ia32_feature_control, X86CPU), 6400779caebSArthur Chunqi Li VMSTATE_END_OF_LIST() 6410779caebSArthur Chunqi Li } 6420779caebSArthur Chunqi Li }; 6430779caebSArthur Chunqi Li 6440d894367SPaolo Bonzini static bool pmu_enable_needed(void *opaque) 6450d894367SPaolo Bonzini { 6460d894367SPaolo Bonzini X86CPU *cpu = opaque; 6470d894367SPaolo Bonzini CPUX86State *env = &cpu->env; 6480d894367SPaolo Bonzini int i; 6490d894367SPaolo Bonzini 6500d894367SPaolo Bonzini if (env->msr_fixed_ctr_ctrl || env->msr_global_ctrl || 6510d894367SPaolo Bonzini env->msr_global_status || env->msr_global_ovf_ctrl) { 6520d894367SPaolo Bonzini return true; 6530d894367SPaolo Bonzini } 6540d894367SPaolo Bonzini for (i = 0; i < MAX_FIXED_COUNTERS; i++) { 6550d894367SPaolo Bonzini if (env->msr_fixed_counters[i]) { 6560d894367SPaolo Bonzini return true; 6570d894367SPaolo Bonzini } 6580d894367SPaolo Bonzini } 6590d894367SPaolo Bonzini for (i = 0; i < MAX_GP_COUNTERS; i++) { 6600d894367SPaolo Bonzini if (env->msr_gp_counters[i] || env->msr_gp_evtsel[i]) { 6610d894367SPaolo Bonzini return true; 6620d894367SPaolo Bonzini } 6630d894367SPaolo Bonzini } 6640d894367SPaolo Bonzini 6650d894367SPaolo Bonzini return false; 6660d894367SPaolo Bonzini } 6670d894367SPaolo Bonzini 6680d894367SPaolo Bonzini static const VMStateDescription vmstate_msr_architectural_pmu = { 6690d894367SPaolo Bonzini .name = "cpu/msr_architectural_pmu", 6700d894367SPaolo Bonzini .version_id = 1, 6710d894367SPaolo Bonzini .minimum_version_id = 1, 6725cd8cadaSJuan Quintela .needed = pmu_enable_needed, 673c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 6740d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_fixed_ctr_ctrl, X86CPU), 6750d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ctrl, X86CPU), 6760d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_status, X86CPU), 6770d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ovf_ctrl, X86CPU), 6780d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_fixed_counters, X86CPU, MAX_FIXED_COUNTERS), 6790d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_counters, X86CPU, MAX_GP_COUNTERS), 6800d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_evtsel, X86CPU, MAX_GP_COUNTERS), 6810d894367SPaolo Bonzini VMSTATE_END_OF_LIST() 6820d894367SPaolo Bonzini } 6830d894367SPaolo Bonzini }; 6840d894367SPaolo Bonzini 68579e9ebebSLiu Jinsong static bool mpx_needed(void *opaque) 68679e9ebebSLiu Jinsong { 68779e9ebebSLiu Jinsong X86CPU *cpu = opaque; 68879e9ebebSLiu Jinsong CPUX86State *env = &cpu->env; 68979e9ebebSLiu Jinsong unsigned int i; 69079e9ebebSLiu Jinsong 69179e9ebebSLiu Jinsong for (i = 0; i < 4; i++) { 69279e9ebebSLiu Jinsong if (env->bnd_regs[i].lb || env->bnd_regs[i].ub) { 69379e9ebebSLiu Jinsong return true; 69479e9ebebSLiu Jinsong } 69579e9ebebSLiu Jinsong } 69679e9ebebSLiu Jinsong 69779e9ebebSLiu Jinsong if (env->bndcs_regs.cfgu || env->bndcs_regs.sts) { 69879e9ebebSLiu Jinsong return true; 69979e9ebebSLiu Jinsong } 70079e9ebebSLiu Jinsong 70179e9ebebSLiu Jinsong return !!env->msr_bndcfgs; 70279e9ebebSLiu Jinsong } 70379e9ebebSLiu Jinsong 70479e9ebebSLiu Jinsong static const VMStateDescription vmstate_mpx = { 70579e9ebebSLiu Jinsong .name = "cpu/mpx", 70679e9ebebSLiu Jinsong .version_id = 1, 70779e9ebebSLiu Jinsong .minimum_version_id = 1, 7085cd8cadaSJuan Quintela .needed = mpx_needed, 709c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 71079e9ebebSLiu Jinsong VMSTATE_BND_REGS(env.bnd_regs, X86CPU, 4), 71179e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.cfgu, X86CPU), 71279e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.sts, X86CPU), 71379e9ebebSLiu Jinsong VMSTATE_UINT64(env.msr_bndcfgs, X86CPU), 71479e9ebebSLiu Jinsong VMSTATE_END_OF_LIST() 71579e9ebebSLiu Jinsong } 71679e9ebebSLiu Jinsong }; 71779e9ebebSLiu Jinsong 7181c90ef26SVadim Rozenfeld static bool hyperv_hypercall_enable_needed(void *opaque) 7191c90ef26SVadim Rozenfeld { 7201c90ef26SVadim Rozenfeld X86CPU *cpu = opaque; 7211c90ef26SVadim Rozenfeld CPUX86State *env = &cpu->env; 7221c90ef26SVadim Rozenfeld 7231c90ef26SVadim Rozenfeld return env->msr_hv_hypercall != 0 || env->msr_hv_guest_os_id != 0; 7241c90ef26SVadim Rozenfeld } 7251c90ef26SVadim Rozenfeld 726816d20c9SVitaly Kuznetsov static const VMStateDescription vmstate_msr_hyperv_hypercall = { 7271c90ef26SVadim Rozenfeld .name = "cpu/msr_hyperv_hypercall", 7281c90ef26SVadim Rozenfeld .version_id = 1, 7291c90ef26SVadim Rozenfeld .minimum_version_id = 1, 7305cd8cadaSJuan Quintela .needed = hyperv_hypercall_enable_needed, 731c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 7321c90ef26SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_guest_os_id, X86CPU), 733466e6e9dSPaolo Bonzini VMSTATE_UINT64(env.msr_hv_hypercall, X86CPU), 7341c90ef26SVadim Rozenfeld VMSTATE_END_OF_LIST() 7351c90ef26SVadim Rozenfeld } 7361c90ef26SVadim Rozenfeld }; 7371c90ef26SVadim Rozenfeld 7385ef68987SVadim Rozenfeld static bool hyperv_vapic_enable_needed(void *opaque) 7395ef68987SVadim Rozenfeld { 7405ef68987SVadim Rozenfeld X86CPU *cpu = opaque; 7415ef68987SVadim Rozenfeld CPUX86State *env = &cpu->env; 7425ef68987SVadim Rozenfeld 7435ef68987SVadim Rozenfeld return env->msr_hv_vapic != 0; 7445ef68987SVadim Rozenfeld } 7455ef68987SVadim Rozenfeld 7465ef68987SVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_vapic = { 7475ef68987SVadim Rozenfeld .name = "cpu/msr_hyperv_vapic", 7485ef68987SVadim Rozenfeld .version_id = 1, 7495ef68987SVadim Rozenfeld .minimum_version_id = 1, 7505cd8cadaSJuan Quintela .needed = hyperv_vapic_enable_needed, 751c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 7525ef68987SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_vapic, X86CPU), 7535ef68987SVadim Rozenfeld VMSTATE_END_OF_LIST() 7545ef68987SVadim Rozenfeld } 7555ef68987SVadim Rozenfeld }; 7565ef68987SVadim Rozenfeld 75748a5f3bcSVadim Rozenfeld static bool hyperv_time_enable_needed(void *opaque) 75848a5f3bcSVadim Rozenfeld { 75948a5f3bcSVadim Rozenfeld X86CPU *cpu = opaque; 76048a5f3bcSVadim Rozenfeld CPUX86State *env = &cpu->env; 76148a5f3bcSVadim Rozenfeld 76248a5f3bcSVadim Rozenfeld return env->msr_hv_tsc != 0; 76348a5f3bcSVadim Rozenfeld } 76448a5f3bcSVadim Rozenfeld 76548a5f3bcSVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_time = { 76648a5f3bcSVadim Rozenfeld .name = "cpu/msr_hyperv_time", 76748a5f3bcSVadim Rozenfeld .version_id = 1, 76848a5f3bcSVadim Rozenfeld .minimum_version_id = 1, 7695cd8cadaSJuan Quintela .needed = hyperv_time_enable_needed, 770c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 77148a5f3bcSVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_tsc, X86CPU), 77248a5f3bcSVadim Rozenfeld VMSTATE_END_OF_LIST() 77348a5f3bcSVadim Rozenfeld } 77448a5f3bcSVadim Rozenfeld }; 77548a5f3bcSVadim Rozenfeld 776f2a53c9eSAndrey Smetanin static bool hyperv_crash_enable_needed(void *opaque) 777f2a53c9eSAndrey Smetanin { 778f2a53c9eSAndrey Smetanin X86CPU *cpu = opaque; 779f2a53c9eSAndrey Smetanin CPUX86State *env = &cpu->env; 780f2a53c9eSAndrey Smetanin int i; 781f2a53c9eSAndrey Smetanin 7825e953812SRoman Kagan for (i = 0; i < HV_CRASH_PARAMS; i++) { 783f2a53c9eSAndrey Smetanin if (env->msr_hv_crash_params[i]) { 784f2a53c9eSAndrey Smetanin return true; 785f2a53c9eSAndrey Smetanin } 786f2a53c9eSAndrey Smetanin } 787f2a53c9eSAndrey Smetanin return false; 788f2a53c9eSAndrey Smetanin } 789f2a53c9eSAndrey Smetanin 790f2a53c9eSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_crash = { 791f2a53c9eSAndrey Smetanin .name = "cpu/msr_hyperv_crash", 792f2a53c9eSAndrey Smetanin .version_id = 1, 793f2a53c9eSAndrey Smetanin .minimum_version_id = 1, 794f2a53c9eSAndrey Smetanin .needed = hyperv_crash_enable_needed, 795c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 7965e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_crash_params, X86CPU, HV_CRASH_PARAMS), 797f2a53c9eSAndrey Smetanin VMSTATE_END_OF_LIST() 798f2a53c9eSAndrey Smetanin } 799f2a53c9eSAndrey Smetanin }; 800f2a53c9eSAndrey Smetanin 80146eb8f98SAndrey Smetanin static bool hyperv_runtime_enable_needed(void *opaque) 80246eb8f98SAndrey Smetanin { 80346eb8f98SAndrey Smetanin X86CPU *cpu = opaque; 80446eb8f98SAndrey Smetanin CPUX86State *env = &cpu->env; 80546eb8f98SAndrey Smetanin 8062d384d7cSVitaly Kuznetsov if (!hyperv_feat_enabled(cpu, HYPERV_FEAT_RUNTIME)) { 80751227875SZhuangYanying return false; 80851227875SZhuangYanying } 80951227875SZhuangYanying 81046eb8f98SAndrey Smetanin return env->msr_hv_runtime != 0; 81146eb8f98SAndrey Smetanin } 81246eb8f98SAndrey Smetanin 81346eb8f98SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_runtime = { 81446eb8f98SAndrey Smetanin .name = "cpu/msr_hyperv_runtime", 81546eb8f98SAndrey Smetanin .version_id = 1, 81646eb8f98SAndrey Smetanin .minimum_version_id = 1, 81746eb8f98SAndrey Smetanin .needed = hyperv_runtime_enable_needed, 818c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 81946eb8f98SAndrey Smetanin VMSTATE_UINT64(env.msr_hv_runtime, X86CPU), 82046eb8f98SAndrey Smetanin VMSTATE_END_OF_LIST() 82146eb8f98SAndrey Smetanin } 82246eb8f98SAndrey Smetanin }; 82346eb8f98SAndrey Smetanin 824866eea9aSAndrey Smetanin static bool hyperv_synic_enable_needed(void *opaque) 825866eea9aSAndrey Smetanin { 826866eea9aSAndrey Smetanin X86CPU *cpu = opaque; 827866eea9aSAndrey Smetanin CPUX86State *env = &cpu->env; 828866eea9aSAndrey Smetanin int i; 829866eea9aSAndrey Smetanin 830866eea9aSAndrey Smetanin if (env->msr_hv_synic_control != 0 || 831866eea9aSAndrey Smetanin env->msr_hv_synic_evt_page != 0 || 832866eea9aSAndrey Smetanin env->msr_hv_synic_msg_page != 0) { 833866eea9aSAndrey Smetanin return true; 834866eea9aSAndrey Smetanin } 835866eea9aSAndrey Smetanin 836866eea9aSAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) { 837866eea9aSAndrey Smetanin if (env->msr_hv_synic_sint[i] != 0) { 838866eea9aSAndrey Smetanin return true; 839866eea9aSAndrey Smetanin } 840866eea9aSAndrey Smetanin } 841866eea9aSAndrey Smetanin 842866eea9aSAndrey Smetanin return false; 843866eea9aSAndrey Smetanin } 844866eea9aSAndrey Smetanin 845606c34bfSRoman Kagan static int hyperv_synic_post_load(void *opaque, int version_id) 846606c34bfSRoman Kagan { 847606c34bfSRoman Kagan X86CPU *cpu = opaque; 848606c34bfSRoman Kagan hyperv_x86_synic_update(cpu); 849606c34bfSRoman Kagan return 0; 850606c34bfSRoman Kagan } 851606c34bfSRoman Kagan 852866eea9aSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_synic = { 853866eea9aSAndrey Smetanin .name = "cpu/msr_hyperv_synic", 854866eea9aSAndrey Smetanin .version_id = 1, 855866eea9aSAndrey Smetanin .minimum_version_id = 1, 856866eea9aSAndrey Smetanin .needed = hyperv_synic_enable_needed, 857606c34bfSRoman Kagan .post_load = hyperv_synic_post_load, 858c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 859866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU), 860866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU), 861866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_msg_page, X86CPU), 8625e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_synic_sint, X86CPU, HV_SINT_COUNT), 863866eea9aSAndrey Smetanin VMSTATE_END_OF_LIST() 864866eea9aSAndrey Smetanin } 865866eea9aSAndrey Smetanin }; 866866eea9aSAndrey Smetanin 867ff99aa64SAndrey Smetanin static bool hyperv_stimer_enable_needed(void *opaque) 868ff99aa64SAndrey Smetanin { 869ff99aa64SAndrey Smetanin X86CPU *cpu = opaque; 870ff99aa64SAndrey Smetanin CPUX86State *env = &cpu->env; 871ff99aa64SAndrey Smetanin int i; 872ff99aa64SAndrey Smetanin 873ff99aa64SAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_stimer_config); i++) { 874ff99aa64SAndrey Smetanin if (env->msr_hv_stimer_config[i] || env->msr_hv_stimer_count[i]) { 875ff99aa64SAndrey Smetanin return true; 876ff99aa64SAndrey Smetanin } 877ff99aa64SAndrey Smetanin } 878ff99aa64SAndrey Smetanin return false; 879ff99aa64SAndrey Smetanin } 880ff99aa64SAndrey Smetanin 881ff99aa64SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_stimer = { 882ff99aa64SAndrey Smetanin .name = "cpu/msr_hyperv_stimer", 883ff99aa64SAndrey Smetanin .version_id = 1, 884ff99aa64SAndrey Smetanin .minimum_version_id = 1, 885ff99aa64SAndrey Smetanin .needed = hyperv_stimer_enable_needed, 886c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 8875e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_config, X86CPU, 8885e953812SRoman Kagan HV_STIMER_COUNT), 8895e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_count, X86CPU, HV_STIMER_COUNT), 890ff99aa64SAndrey Smetanin VMSTATE_END_OF_LIST() 891ff99aa64SAndrey Smetanin } 892ff99aa64SAndrey Smetanin }; 893ff99aa64SAndrey Smetanin 894ba6a4fd9SVitaly Kuznetsov static bool hyperv_reenlightenment_enable_needed(void *opaque) 895ba6a4fd9SVitaly Kuznetsov { 896ba6a4fd9SVitaly Kuznetsov X86CPU *cpu = opaque; 897ba6a4fd9SVitaly Kuznetsov CPUX86State *env = &cpu->env; 898ba6a4fd9SVitaly Kuznetsov 899ba6a4fd9SVitaly Kuznetsov return env->msr_hv_reenlightenment_control != 0 || 900ba6a4fd9SVitaly Kuznetsov env->msr_hv_tsc_emulation_control != 0 || 901ba6a4fd9SVitaly Kuznetsov env->msr_hv_tsc_emulation_status != 0; 902ba6a4fd9SVitaly Kuznetsov } 903ba6a4fd9SVitaly Kuznetsov 904561dbb41SVitaly Kuznetsov static int hyperv_reenlightenment_post_load(void *opaque, int version_id) 905561dbb41SVitaly Kuznetsov { 906561dbb41SVitaly Kuznetsov X86CPU *cpu = opaque; 907561dbb41SVitaly Kuznetsov CPUX86State *env = &cpu->env; 908561dbb41SVitaly Kuznetsov 909561dbb41SVitaly Kuznetsov /* 910561dbb41SVitaly Kuznetsov * KVM doesn't fully support re-enlightenment notifications so we need to 911561dbb41SVitaly Kuznetsov * make sure TSC frequency doesn't change upon migration. 912561dbb41SVitaly Kuznetsov */ 913561dbb41SVitaly Kuznetsov if ((env->msr_hv_reenlightenment_control & HV_REENLIGHTENMENT_ENABLE_BIT) && 914561dbb41SVitaly Kuznetsov !env->user_tsc_khz) { 915561dbb41SVitaly Kuznetsov error_report("Guest enabled re-enlightenment notifications, " 916561dbb41SVitaly Kuznetsov "'tsc-frequency=' has to be specified"); 917561dbb41SVitaly Kuznetsov return -EINVAL; 918561dbb41SVitaly Kuznetsov } 919561dbb41SVitaly Kuznetsov 920561dbb41SVitaly Kuznetsov return 0; 921561dbb41SVitaly Kuznetsov } 922561dbb41SVitaly Kuznetsov 923ba6a4fd9SVitaly Kuznetsov static const VMStateDescription vmstate_msr_hyperv_reenlightenment = { 924ba6a4fd9SVitaly Kuznetsov .name = "cpu/msr_hyperv_reenlightenment", 925ba6a4fd9SVitaly Kuznetsov .version_id = 1, 926ba6a4fd9SVitaly Kuznetsov .minimum_version_id = 1, 927ba6a4fd9SVitaly Kuznetsov .needed = hyperv_reenlightenment_enable_needed, 928561dbb41SVitaly Kuznetsov .post_load = hyperv_reenlightenment_post_load, 929c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 930ba6a4fd9SVitaly Kuznetsov VMSTATE_UINT64(env.msr_hv_reenlightenment_control, X86CPU), 931ba6a4fd9SVitaly Kuznetsov VMSTATE_UINT64(env.msr_hv_tsc_emulation_control, X86CPU), 932ba6a4fd9SVitaly Kuznetsov VMSTATE_UINT64(env.msr_hv_tsc_emulation_status, X86CPU), 933ba6a4fd9SVitaly Kuznetsov VMSTATE_END_OF_LIST() 934ba6a4fd9SVitaly Kuznetsov } 935ba6a4fd9SVitaly Kuznetsov }; 936ba6a4fd9SVitaly Kuznetsov 9379aecd6f8SChao Peng static bool avx512_needed(void *opaque) 9389aecd6f8SChao Peng { 9399aecd6f8SChao Peng X86CPU *cpu = opaque; 9409aecd6f8SChao Peng CPUX86State *env = &cpu->env; 9419aecd6f8SChao Peng unsigned int i; 9429aecd6f8SChao Peng 9439aecd6f8SChao Peng for (i = 0; i < NB_OPMASK_REGS; i++) { 9449aecd6f8SChao Peng if (env->opmask_regs[i]) { 9459aecd6f8SChao Peng return true; 9469aecd6f8SChao Peng } 9479aecd6f8SChao Peng } 9489aecd6f8SChao Peng 9499aecd6f8SChao Peng for (i = 0; i < CPU_NB_REGS; i++) { 95019cbd87cSEduardo Habkost #define ENV_XMM(reg, field) (env->xmm_regs[reg].ZMM_Q(field)) 951b7711471SPaolo Bonzini if (ENV_XMM(i, 4) || ENV_XMM(i, 6) || 952b7711471SPaolo Bonzini ENV_XMM(i, 5) || ENV_XMM(i, 7)) { 9539aecd6f8SChao Peng return true; 9549aecd6f8SChao Peng } 9559aecd6f8SChao Peng #ifdef TARGET_X86_64 956b7711471SPaolo Bonzini if (ENV_XMM(i+16, 0) || ENV_XMM(i+16, 1) || 957b7711471SPaolo Bonzini ENV_XMM(i+16, 2) || ENV_XMM(i+16, 3) || 958b7711471SPaolo Bonzini ENV_XMM(i+16, 4) || ENV_XMM(i+16, 5) || 959b7711471SPaolo Bonzini ENV_XMM(i+16, 6) || ENV_XMM(i+16, 7)) { 9609aecd6f8SChao Peng return true; 9619aecd6f8SChao Peng } 9629aecd6f8SChao Peng #endif 9639aecd6f8SChao Peng } 9649aecd6f8SChao Peng 9659aecd6f8SChao Peng return false; 9669aecd6f8SChao Peng } 9679aecd6f8SChao Peng 9689aecd6f8SChao Peng static const VMStateDescription vmstate_avx512 = { 9699aecd6f8SChao Peng .name = "cpu/avx512", 9709aecd6f8SChao Peng .version_id = 1, 9719aecd6f8SChao Peng .minimum_version_id = 1, 9725cd8cadaSJuan Quintela .needed = avx512_needed, 973c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 9749aecd6f8SChao Peng VMSTATE_UINT64_ARRAY(env.opmask_regs, X86CPU, NB_OPMASK_REGS), 975b7711471SPaolo Bonzini VMSTATE_ZMMH_REGS_VARS(env.xmm_regs, X86CPU, 0), 9769aecd6f8SChao Peng #ifdef TARGET_X86_64 977b7711471SPaolo Bonzini VMSTATE_Hi16_ZMM_REGS_VARS(env.xmm_regs, X86CPU, 16), 9789aecd6f8SChao Peng #endif 9799aecd6f8SChao Peng VMSTATE_END_OF_LIST() 9809aecd6f8SChao Peng } 9819aecd6f8SChao Peng }; 9829aecd6f8SChao Peng 98318cd2c17SWanpeng Li static bool xss_needed(void *opaque) 98418cd2c17SWanpeng Li { 98518cd2c17SWanpeng Li X86CPU *cpu = opaque; 98618cd2c17SWanpeng Li CPUX86State *env = &cpu->env; 98718cd2c17SWanpeng Li 98818cd2c17SWanpeng Li return env->xss != 0; 98918cd2c17SWanpeng Li } 99018cd2c17SWanpeng Li 99118cd2c17SWanpeng Li static const VMStateDescription vmstate_xss = { 99218cd2c17SWanpeng Li .name = "cpu/xss", 99318cd2c17SWanpeng Li .version_id = 1, 99418cd2c17SWanpeng Li .minimum_version_id = 1, 9955cd8cadaSJuan Quintela .needed = xss_needed, 996c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 99718cd2c17SWanpeng Li VMSTATE_UINT64(env.xss, X86CPU), 99818cd2c17SWanpeng Li VMSTATE_END_OF_LIST() 99918cd2c17SWanpeng Li } 100018cd2c17SWanpeng Li }; 100118cd2c17SWanpeng Li 100265087997STao Xu static bool umwait_needed(void *opaque) 100365087997STao Xu { 100465087997STao Xu X86CPU *cpu = opaque; 100565087997STao Xu CPUX86State *env = &cpu->env; 100665087997STao Xu 100765087997STao Xu return env->umwait != 0; 100865087997STao Xu } 100965087997STao Xu 101065087997STao Xu static const VMStateDescription vmstate_umwait = { 101165087997STao Xu .name = "cpu/umwait", 101265087997STao Xu .version_id = 1, 101365087997STao Xu .minimum_version_id = 1, 101465087997STao Xu .needed = umwait_needed, 1015c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 101665087997STao Xu VMSTATE_UINT32(env.umwait, X86CPU), 101765087997STao Xu VMSTATE_END_OF_LIST() 101865087997STao Xu } 101965087997STao Xu }; 102065087997STao Xu 1021f74eefe0SHuaitong Han static bool pkru_needed(void *opaque) 1022f74eefe0SHuaitong Han { 1023f74eefe0SHuaitong Han X86CPU *cpu = opaque; 1024f74eefe0SHuaitong Han CPUX86State *env = &cpu->env; 1025f74eefe0SHuaitong Han 1026f74eefe0SHuaitong Han return env->pkru != 0; 1027f74eefe0SHuaitong Han } 1028f74eefe0SHuaitong Han 1029f74eefe0SHuaitong Han static const VMStateDescription vmstate_pkru = { 1030f74eefe0SHuaitong Han .name = "cpu/pkru", 1031f74eefe0SHuaitong Han .version_id = 1, 1032f74eefe0SHuaitong Han .minimum_version_id = 1, 1033f74eefe0SHuaitong Han .needed = pkru_needed, 1034c4f54bd6SRichard Henderson .fields = (const VMStateField[]){ 1035f74eefe0SHuaitong Han VMSTATE_UINT32(env.pkru, X86CPU), 1036f74eefe0SHuaitong Han VMSTATE_END_OF_LIST() 1037f74eefe0SHuaitong Han } 1038f74eefe0SHuaitong Han }; 1039e7e7bdabSPaolo Bonzini 1040e7e7bdabSPaolo Bonzini static bool pkrs_needed(void *opaque) 1041e7e7bdabSPaolo Bonzini { 1042e7e7bdabSPaolo Bonzini X86CPU *cpu = opaque; 1043e7e7bdabSPaolo Bonzini CPUX86State *env = &cpu->env; 1044e7e7bdabSPaolo Bonzini 1045e7e7bdabSPaolo Bonzini return env->pkrs != 0; 1046e7e7bdabSPaolo Bonzini } 1047e7e7bdabSPaolo Bonzini 1048e7e7bdabSPaolo Bonzini static const VMStateDescription vmstate_pkrs = { 1049e7e7bdabSPaolo Bonzini .name = "cpu/pkrs", 1050e7e7bdabSPaolo Bonzini .version_id = 1, 1051e7e7bdabSPaolo Bonzini .minimum_version_id = 1, 1052e7e7bdabSPaolo Bonzini .needed = pkrs_needed, 1053c4f54bd6SRichard Henderson .fields = (const VMStateField[]){ 1054e7e7bdabSPaolo Bonzini VMSTATE_UINT32(env.pkrs, X86CPU), 1055e7e7bdabSPaolo Bonzini VMSTATE_END_OF_LIST() 1056e7e7bdabSPaolo Bonzini } 1057e7e7bdabSPaolo Bonzini }; 1058f74eefe0SHuaitong Han 105936f96c4bSHaozhong Zhang static bool tsc_khz_needed(void *opaque) 106036f96c4bSHaozhong Zhang { 106136f96c4bSHaozhong Zhang X86CPU *cpu = opaque; 106236f96c4bSHaozhong Zhang CPUX86State *env = &cpu->env; 106336f96c4bSHaozhong Zhang MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); 10642f34ebf2SLiam Merwick X86MachineClass *x86mc = X86_MACHINE_CLASS(mc); 10652f34ebf2SLiam Merwick return env->tsc_khz && x86mc->save_tsc_khz; 106636f96c4bSHaozhong Zhang } 106736f96c4bSHaozhong Zhang 106836f96c4bSHaozhong Zhang static const VMStateDescription vmstate_tsc_khz = { 106936f96c4bSHaozhong Zhang .name = "cpu/tsc_khz", 107036f96c4bSHaozhong Zhang .version_id = 1, 107136f96c4bSHaozhong Zhang .minimum_version_id = 1, 107236f96c4bSHaozhong Zhang .needed = tsc_khz_needed, 1073c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 107436f96c4bSHaozhong Zhang VMSTATE_INT64(env.tsc_khz, X86CPU), 107536f96c4bSHaozhong Zhang VMSTATE_END_OF_LIST() 107636f96c4bSHaozhong Zhang } 107736f96c4bSHaozhong Zhang }; 107836f96c4bSHaozhong Zhang 1079ebbfef2fSLiran Alon #ifdef CONFIG_KVM 1080ebbfef2fSLiran Alon 1081ebbfef2fSLiran Alon static bool vmx_vmcs12_needed(void *opaque) 1082ebbfef2fSLiran Alon { 1083ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = opaque; 1084ebbfef2fSLiran Alon return (nested_state->size > 1085ebbfef2fSLiran Alon offsetof(struct kvm_nested_state, data.vmx[0].vmcs12)); 1086ebbfef2fSLiran Alon } 1087ebbfef2fSLiran Alon 1088ebbfef2fSLiran Alon static const VMStateDescription vmstate_vmx_vmcs12 = { 1089ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state/vmx/vmcs12", 1090ebbfef2fSLiran Alon .version_id = 1, 1091ebbfef2fSLiran Alon .minimum_version_id = 1, 1092ebbfef2fSLiran Alon .needed = vmx_vmcs12_needed, 1093c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1094ebbfef2fSLiran Alon VMSTATE_UINT8_ARRAY(data.vmx[0].vmcs12, 1095ebbfef2fSLiran Alon struct kvm_nested_state, 1096ebbfef2fSLiran Alon KVM_STATE_NESTED_VMX_VMCS_SIZE), 1097ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1098ebbfef2fSLiran Alon } 1099ebbfef2fSLiran Alon }; 1100ebbfef2fSLiran Alon 1101ebbfef2fSLiran Alon static bool vmx_shadow_vmcs12_needed(void *opaque) 1102ebbfef2fSLiran Alon { 1103ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = opaque; 1104ebbfef2fSLiran Alon return (nested_state->size > 1105ebbfef2fSLiran Alon offsetof(struct kvm_nested_state, data.vmx[0].shadow_vmcs12)); 1106ebbfef2fSLiran Alon } 1107ebbfef2fSLiran Alon 1108ebbfef2fSLiran Alon static const VMStateDescription vmstate_vmx_shadow_vmcs12 = { 1109ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state/vmx/shadow_vmcs12", 1110ebbfef2fSLiran Alon .version_id = 1, 1111ebbfef2fSLiran Alon .minimum_version_id = 1, 1112ebbfef2fSLiran Alon .needed = vmx_shadow_vmcs12_needed, 1113c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1114ebbfef2fSLiran Alon VMSTATE_UINT8_ARRAY(data.vmx[0].shadow_vmcs12, 1115ebbfef2fSLiran Alon struct kvm_nested_state, 1116ebbfef2fSLiran Alon KVM_STATE_NESTED_VMX_VMCS_SIZE), 1117ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1118ebbfef2fSLiran Alon } 1119ebbfef2fSLiran Alon }; 1120ebbfef2fSLiran Alon 1121ebbfef2fSLiran Alon static bool vmx_nested_state_needed(void *opaque) 1122ebbfef2fSLiran Alon { 1123ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = opaque; 1124ebbfef2fSLiran Alon 1125ec7b1bbdSLiran Alon return (nested_state->format == KVM_STATE_NESTED_FORMAT_VMX && 1126ec7b1bbdSLiran Alon nested_state->hdr.vmx.vmxon_pa != -1ull); 1127ebbfef2fSLiran Alon } 1128ebbfef2fSLiran Alon 1129ebbfef2fSLiran Alon static const VMStateDescription vmstate_vmx_nested_state = { 1130ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state/vmx", 1131ebbfef2fSLiran Alon .version_id = 1, 1132ebbfef2fSLiran Alon .minimum_version_id = 1, 1133ebbfef2fSLiran Alon .needed = vmx_nested_state_needed, 1134c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1135ebbfef2fSLiran Alon VMSTATE_U64(hdr.vmx.vmxon_pa, struct kvm_nested_state), 1136ebbfef2fSLiran Alon VMSTATE_U64(hdr.vmx.vmcs12_pa, struct kvm_nested_state), 1137ebbfef2fSLiran Alon VMSTATE_U16(hdr.vmx.smm.flags, struct kvm_nested_state), 1138ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1139ebbfef2fSLiran Alon }, 1140c4f54bd6SRichard Henderson .subsections = (const VMStateDescription * const []) { 1141ebbfef2fSLiran Alon &vmstate_vmx_vmcs12, 1142ebbfef2fSLiran Alon &vmstate_vmx_shadow_vmcs12, 1143ebbfef2fSLiran Alon NULL, 1144ebbfef2fSLiran Alon } 1145ebbfef2fSLiran Alon }; 1146ebbfef2fSLiran Alon 1147b16c0e20SPaolo Bonzini static bool svm_nested_state_needed(void *opaque) 1148b16c0e20SPaolo Bonzini { 1149b16c0e20SPaolo Bonzini struct kvm_nested_state *nested_state = opaque; 1150b16c0e20SPaolo Bonzini 1151b16c0e20SPaolo Bonzini /* 1152b16c0e20SPaolo Bonzini * HF_GUEST_MASK and HF2_GIF_MASK are already serialized 1153b16c0e20SPaolo Bonzini * via hflags and hflags2, all that's left is the opaque 1154b16c0e20SPaolo Bonzini * nested state blob. 1155b16c0e20SPaolo Bonzini */ 1156b16c0e20SPaolo Bonzini return (nested_state->format == KVM_STATE_NESTED_FORMAT_SVM && 1157b16c0e20SPaolo Bonzini nested_state->size > offsetof(struct kvm_nested_state, data)); 1158b16c0e20SPaolo Bonzini } 1159b16c0e20SPaolo Bonzini 1160b16c0e20SPaolo Bonzini static const VMStateDescription vmstate_svm_nested_state = { 1161b16c0e20SPaolo Bonzini .name = "cpu/kvm_nested_state/svm", 1162b16c0e20SPaolo Bonzini .version_id = 1, 1163b16c0e20SPaolo Bonzini .minimum_version_id = 1, 1164b16c0e20SPaolo Bonzini .needed = svm_nested_state_needed, 1165c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1166b16c0e20SPaolo Bonzini VMSTATE_U64(hdr.svm.vmcb_pa, struct kvm_nested_state), 1167b16c0e20SPaolo Bonzini VMSTATE_UINT8_ARRAY(data.svm[0].vmcb12, 1168b16c0e20SPaolo Bonzini struct kvm_nested_state, 1169b16c0e20SPaolo Bonzini KVM_STATE_NESTED_SVM_VMCB_SIZE), 1170b16c0e20SPaolo Bonzini VMSTATE_END_OF_LIST() 1171b16c0e20SPaolo Bonzini } 1172b16c0e20SPaolo Bonzini }; 1173b16c0e20SPaolo Bonzini 1174ebbfef2fSLiran Alon static bool nested_state_needed(void *opaque) 1175ebbfef2fSLiran Alon { 1176ebbfef2fSLiran Alon X86CPU *cpu = opaque; 1177ebbfef2fSLiran Alon CPUX86State *env = &cpu->env; 1178ebbfef2fSLiran Alon 1179ebbfef2fSLiran Alon return (env->nested_state && 1180b16c0e20SPaolo Bonzini (vmx_nested_state_needed(env->nested_state) || 1181b16c0e20SPaolo Bonzini svm_nested_state_needed(env->nested_state))); 1182ebbfef2fSLiran Alon } 1183ebbfef2fSLiran Alon 1184ebbfef2fSLiran Alon static int nested_state_post_load(void *opaque, int version_id) 1185ebbfef2fSLiran Alon { 1186ebbfef2fSLiran Alon X86CPU *cpu = opaque; 1187ebbfef2fSLiran Alon CPUX86State *env = &cpu->env; 1188ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = env->nested_state; 1189ebbfef2fSLiran Alon int min_nested_state_len = offsetof(struct kvm_nested_state, data); 1190ebbfef2fSLiran Alon int max_nested_state_len = kvm_max_nested_state_length(); 1191ebbfef2fSLiran Alon 1192ebbfef2fSLiran Alon /* 1193ebbfef2fSLiran Alon * If our kernel don't support setting nested state 1194ebbfef2fSLiran Alon * and we have received nested state from migration stream, 1195ebbfef2fSLiran Alon * we need to fail migration 1196ebbfef2fSLiran Alon */ 1197ebbfef2fSLiran Alon if (max_nested_state_len <= 0) { 1198ebbfef2fSLiran Alon error_report("Received nested state when kernel cannot restore it"); 1199ebbfef2fSLiran Alon return -EINVAL; 1200ebbfef2fSLiran Alon } 1201ebbfef2fSLiran Alon 1202ebbfef2fSLiran Alon /* 1203ebbfef2fSLiran Alon * Verify that the size of received nested_state struct 1204ebbfef2fSLiran Alon * at least cover required header and is not larger 1205ebbfef2fSLiran Alon * than the max size that our kernel support 1206ebbfef2fSLiran Alon */ 1207ebbfef2fSLiran Alon if (nested_state->size < min_nested_state_len) { 1208ebbfef2fSLiran Alon error_report("Received nested state size less than min: " 1209ebbfef2fSLiran Alon "len=%d, min=%d", 1210ebbfef2fSLiran Alon nested_state->size, min_nested_state_len); 1211ebbfef2fSLiran Alon return -EINVAL; 1212ebbfef2fSLiran Alon } 1213ebbfef2fSLiran Alon if (nested_state->size > max_nested_state_len) { 1214cba42d61SMichael Tokarev error_report("Received unsupported nested state size: " 1215ebbfef2fSLiran Alon "nested_state->size=%d, max=%d", 1216ebbfef2fSLiran Alon nested_state->size, max_nested_state_len); 1217ebbfef2fSLiran Alon return -EINVAL; 1218ebbfef2fSLiran Alon } 1219ebbfef2fSLiran Alon 1220ebbfef2fSLiran Alon /* Verify format is valid */ 1221ebbfef2fSLiran Alon if ((nested_state->format != KVM_STATE_NESTED_FORMAT_VMX) && 1222ebbfef2fSLiran Alon (nested_state->format != KVM_STATE_NESTED_FORMAT_SVM)) { 1223ebbfef2fSLiran Alon error_report("Received invalid nested state format: %d", 1224ebbfef2fSLiran Alon nested_state->format); 1225ebbfef2fSLiran Alon return -EINVAL; 1226ebbfef2fSLiran Alon } 1227ebbfef2fSLiran Alon 1228ebbfef2fSLiran Alon return 0; 1229ebbfef2fSLiran Alon } 1230ebbfef2fSLiran Alon 1231ebbfef2fSLiran Alon static const VMStateDescription vmstate_kvm_nested_state = { 1232ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state", 1233ebbfef2fSLiran Alon .version_id = 1, 1234ebbfef2fSLiran Alon .minimum_version_id = 1, 1235c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1236ebbfef2fSLiran Alon VMSTATE_U16(flags, struct kvm_nested_state), 1237ebbfef2fSLiran Alon VMSTATE_U16(format, struct kvm_nested_state), 1238ebbfef2fSLiran Alon VMSTATE_U32(size, struct kvm_nested_state), 1239ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1240ebbfef2fSLiran Alon }, 1241c4f54bd6SRichard Henderson .subsections = (const VMStateDescription * const []) { 1242ebbfef2fSLiran Alon &vmstate_vmx_nested_state, 1243b16c0e20SPaolo Bonzini &vmstate_svm_nested_state, 1244ebbfef2fSLiran Alon NULL 1245ebbfef2fSLiran Alon } 1246ebbfef2fSLiran Alon }; 1247ebbfef2fSLiran Alon 1248ebbfef2fSLiran Alon static const VMStateDescription vmstate_nested_state = { 1249ebbfef2fSLiran Alon .name = "cpu/nested_state", 1250ebbfef2fSLiran Alon .version_id = 1, 1251ebbfef2fSLiran Alon .minimum_version_id = 1, 1252ebbfef2fSLiran Alon .needed = nested_state_needed, 1253ebbfef2fSLiran Alon .post_load = nested_state_post_load, 1254c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1255ebbfef2fSLiran Alon VMSTATE_STRUCT_POINTER(env.nested_state, X86CPU, 1256ebbfef2fSLiran Alon vmstate_kvm_nested_state, 1257ebbfef2fSLiran Alon struct kvm_nested_state), 1258ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1259ebbfef2fSLiran Alon } 1260ebbfef2fSLiran Alon }; 1261ebbfef2fSLiran Alon 1262c345104cSJoao Martins static bool xen_vcpu_needed(void *opaque) 1263c345104cSJoao Martins { 1264c345104cSJoao Martins return (xen_mode == XEN_EMULATE); 1265c345104cSJoao Martins } 1266c345104cSJoao Martins 1267c345104cSJoao Martins static const VMStateDescription vmstate_xen_vcpu = { 1268c345104cSJoao Martins .name = "cpu/xen_vcpu", 1269c345104cSJoao Martins .version_id = 1, 1270c345104cSJoao Martins .minimum_version_id = 1, 1271c345104cSJoao Martins .needed = xen_vcpu_needed, 1272c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1273c345104cSJoao Martins VMSTATE_UINT64(env.xen_vcpu_info_gpa, X86CPU), 1274c345104cSJoao Martins VMSTATE_UINT64(env.xen_vcpu_info_default_gpa, X86CPU), 1275f0689302SJoao Martins VMSTATE_UINT64(env.xen_vcpu_time_info_gpa, X86CPU), 12765092db87SJoao Martins VMSTATE_UINT64(env.xen_vcpu_runstate_gpa, X86CPU), 1277105b47fdSAnkur Arora VMSTATE_UINT8(env.xen_vcpu_callback_vector, X86CPU), 1278c723d4c1SDavid Woodhouse VMSTATE_UINT16_ARRAY(env.xen_virq, X86CPU, XEN_NR_VIRQS), 1279c723d4c1SDavid Woodhouse VMSTATE_UINT64(env.xen_singleshot_timer_ns, X86CPU), 1280b746a779SJoao Martins VMSTATE_UINT64(env.xen_periodic_timer_period, X86CPU), 1281c345104cSJoao Martins VMSTATE_END_OF_LIST() 1282c345104cSJoao Martins } 1283c345104cSJoao Martins }; 1284ebbfef2fSLiran Alon #endif 1285ebbfef2fSLiran Alon 128687f8b626SAshok Raj static bool mcg_ext_ctl_needed(void *opaque) 128787f8b626SAshok Raj { 128887f8b626SAshok Raj X86CPU *cpu = opaque; 128987f8b626SAshok Raj CPUX86State *env = &cpu->env; 129087f8b626SAshok Raj return cpu->enable_lmce && env->mcg_ext_ctl; 129187f8b626SAshok Raj } 129287f8b626SAshok Raj 129387f8b626SAshok Raj static const VMStateDescription vmstate_mcg_ext_ctl = { 129487f8b626SAshok Raj .name = "cpu/mcg_ext_ctl", 129587f8b626SAshok Raj .version_id = 1, 129687f8b626SAshok Raj .minimum_version_id = 1, 129787f8b626SAshok Raj .needed = mcg_ext_ctl_needed, 1298c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 129987f8b626SAshok Raj VMSTATE_UINT64(env.mcg_ext_ctl, X86CPU), 130087f8b626SAshok Raj VMSTATE_END_OF_LIST() 130187f8b626SAshok Raj } 130287f8b626SAshok Raj }; 130387f8b626SAshok Raj 1304a33a2cfeSPaolo Bonzini static bool spec_ctrl_needed(void *opaque) 1305a33a2cfeSPaolo Bonzini { 1306a33a2cfeSPaolo Bonzini X86CPU *cpu = opaque; 1307a33a2cfeSPaolo Bonzini CPUX86State *env = &cpu->env; 1308a33a2cfeSPaolo Bonzini 1309a33a2cfeSPaolo Bonzini return env->spec_ctrl != 0; 1310a33a2cfeSPaolo Bonzini } 1311a33a2cfeSPaolo Bonzini 1312a33a2cfeSPaolo Bonzini static const VMStateDescription vmstate_spec_ctrl = { 1313a33a2cfeSPaolo Bonzini .name = "cpu/spec_ctrl", 1314a33a2cfeSPaolo Bonzini .version_id = 1, 1315a33a2cfeSPaolo Bonzini .minimum_version_id = 1, 1316a33a2cfeSPaolo Bonzini .needed = spec_ctrl_needed, 1317c4f54bd6SRichard Henderson .fields = (const VMStateField[]){ 1318a33a2cfeSPaolo Bonzini VMSTATE_UINT64(env.spec_ctrl, X86CPU), 1319a33a2cfeSPaolo Bonzini VMSTATE_END_OF_LIST() 1320a33a2cfeSPaolo Bonzini } 1321a33a2cfeSPaolo Bonzini }; 1322a33a2cfeSPaolo Bonzini 1323cabf9862SMaxim Levitsky 1324cabf9862SMaxim Levitsky static bool amd_tsc_scale_msr_needed(void *opaque) 1325cabf9862SMaxim Levitsky { 1326cabf9862SMaxim Levitsky X86CPU *cpu = opaque; 1327cabf9862SMaxim Levitsky CPUX86State *env = &cpu->env; 1328cabf9862SMaxim Levitsky 1329cabf9862SMaxim Levitsky return (env->features[FEAT_SVM] & CPUID_SVM_TSCSCALE); 1330cabf9862SMaxim Levitsky } 1331cabf9862SMaxim Levitsky 1332cabf9862SMaxim Levitsky static const VMStateDescription amd_tsc_scale_msr_ctrl = { 1333cabf9862SMaxim Levitsky .name = "cpu/amd_tsc_scale_msr", 1334cabf9862SMaxim Levitsky .version_id = 1, 1335cabf9862SMaxim Levitsky .minimum_version_id = 1, 1336cabf9862SMaxim Levitsky .needed = amd_tsc_scale_msr_needed, 1337c4f54bd6SRichard Henderson .fields = (const VMStateField[]){ 1338cabf9862SMaxim Levitsky VMSTATE_UINT64(env.amd_tsc_scale_msr, X86CPU), 1339cabf9862SMaxim Levitsky VMSTATE_END_OF_LIST() 1340cabf9862SMaxim Levitsky } 1341cabf9862SMaxim Levitsky }; 1342cabf9862SMaxim Levitsky 1343cabf9862SMaxim Levitsky 1344b77146e9SChao Peng static bool intel_pt_enable_needed(void *opaque) 1345b77146e9SChao Peng { 1346b77146e9SChao Peng X86CPU *cpu = opaque; 1347b77146e9SChao Peng CPUX86State *env = &cpu->env; 1348b77146e9SChao Peng int i; 1349b77146e9SChao Peng 1350b77146e9SChao Peng if (env->msr_rtit_ctrl || env->msr_rtit_status || 1351b77146e9SChao Peng env->msr_rtit_output_base || env->msr_rtit_output_mask || 1352b77146e9SChao Peng env->msr_rtit_cr3_match) { 1353b77146e9SChao Peng return true; 1354b77146e9SChao Peng } 1355b77146e9SChao Peng 1356b77146e9SChao Peng for (i = 0; i < MAX_RTIT_ADDRS; i++) { 1357b77146e9SChao Peng if (env->msr_rtit_addrs[i]) { 1358b77146e9SChao Peng return true; 1359b77146e9SChao Peng } 1360b77146e9SChao Peng } 1361b77146e9SChao Peng 1362b77146e9SChao Peng return false; 1363b77146e9SChao Peng } 1364b77146e9SChao Peng 1365b77146e9SChao Peng static const VMStateDescription vmstate_msr_intel_pt = { 1366b77146e9SChao Peng .name = "cpu/intel_pt", 1367b77146e9SChao Peng .version_id = 1, 1368b77146e9SChao Peng .minimum_version_id = 1, 1369b77146e9SChao Peng .needed = intel_pt_enable_needed, 1370c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1371b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_ctrl, X86CPU), 1372b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_status, X86CPU), 1373b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_output_base, X86CPU), 1374b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_output_mask, X86CPU), 1375b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_cr3_match, X86CPU), 1376b77146e9SChao Peng VMSTATE_UINT64_ARRAY(env.msr_rtit_addrs, X86CPU, MAX_RTIT_ADDRS), 1377b77146e9SChao Peng VMSTATE_END_OF_LIST() 1378b77146e9SChao Peng } 1379b77146e9SChao Peng }; 1380b77146e9SChao Peng 1381cfeea0c0SKonrad Rzeszutek Wilk static bool virt_ssbd_needed(void *opaque) 1382cfeea0c0SKonrad Rzeszutek Wilk { 1383cfeea0c0SKonrad Rzeszutek Wilk X86CPU *cpu = opaque; 1384cfeea0c0SKonrad Rzeszutek Wilk CPUX86State *env = &cpu->env; 1385cfeea0c0SKonrad Rzeszutek Wilk 1386cfeea0c0SKonrad Rzeszutek Wilk return env->virt_ssbd != 0; 1387cfeea0c0SKonrad Rzeszutek Wilk } 1388cfeea0c0SKonrad Rzeszutek Wilk 1389cfeea0c0SKonrad Rzeszutek Wilk static const VMStateDescription vmstate_msr_virt_ssbd = { 1390cfeea0c0SKonrad Rzeszutek Wilk .name = "cpu/virt_ssbd", 1391cfeea0c0SKonrad Rzeszutek Wilk .version_id = 1, 1392cfeea0c0SKonrad Rzeszutek Wilk .minimum_version_id = 1, 1393cfeea0c0SKonrad Rzeszutek Wilk .needed = virt_ssbd_needed, 1394c4f54bd6SRichard Henderson .fields = (const VMStateField[]){ 1395cfeea0c0SKonrad Rzeszutek Wilk VMSTATE_UINT64(env.virt_ssbd, X86CPU), 1396cfeea0c0SKonrad Rzeszutek Wilk VMSTATE_END_OF_LIST() 1397cfeea0c0SKonrad Rzeszutek Wilk } 1398cfeea0c0SKonrad Rzeszutek Wilk }; 1399cfeea0c0SKonrad Rzeszutek Wilk 1400fe441054SJan Kiszka static bool svm_npt_needed(void *opaque) 1401fe441054SJan Kiszka { 1402fe441054SJan Kiszka X86CPU *cpu = opaque; 1403fe441054SJan Kiszka CPUX86State *env = &cpu->env; 1404fe441054SJan Kiszka 1405fe441054SJan Kiszka return !!(env->hflags2 & HF2_NPT_MASK); 1406fe441054SJan Kiszka } 1407fe441054SJan Kiszka 1408fe441054SJan Kiszka static const VMStateDescription vmstate_svm_npt = { 1409fe441054SJan Kiszka .name = "cpu/svn_npt", 1410fe441054SJan Kiszka .version_id = 1, 1411fe441054SJan Kiszka .minimum_version_id = 1, 1412fe441054SJan Kiszka .needed = svm_npt_needed, 1413c4f54bd6SRichard Henderson .fields = (const VMStateField[]){ 1414fe441054SJan Kiszka VMSTATE_UINT64(env.nested_cr3, X86CPU), 1415fe441054SJan Kiszka VMSTATE_UINT32(env.nested_pg_mode, X86CPU), 1416fe441054SJan Kiszka VMSTATE_END_OF_LIST() 1417fe441054SJan Kiszka } 1418fe441054SJan Kiszka }; 1419fe441054SJan Kiszka 1420e3126a5cSLara Lazier static bool svm_guest_needed(void *opaque) 1421e3126a5cSLara Lazier { 1422e3126a5cSLara Lazier X86CPU *cpu = opaque; 1423e3126a5cSLara Lazier CPUX86State *env = &cpu->env; 1424e3126a5cSLara Lazier 1425e3126a5cSLara Lazier return tcg_enabled() && env->int_ctl; 1426e3126a5cSLara Lazier } 1427e3126a5cSLara Lazier 1428e3126a5cSLara Lazier static const VMStateDescription vmstate_svm_guest = { 1429e3126a5cSLara Lazier .name = "cpu/svm_guest", 1430e3126a5cSLara Lazier .version_id = 1, 1431e3126a5cSLara Lazier .minimum_version_id = 1, 1432e3126a5cSLara Lazier .needed = svm_guest_needed, 1433c4f54bd6SRichard Henderson .fields = (const VMStateField[]){ 1434e3126a5cSLara Lazier VMSTATE_UINT32(env.int_ctl, X86CPU), 1435e3126a5cSLara Lazier VMSTATE_END_OF_LIST() 1436e3126a5cSLara Lazier } 1437e3126a5cSLara Lazier }; 1438e3126a5cSLara Lazier 143989a44a10SPavel Dovgalyuk #ifndef TARGET_X86_64 144089a44a10SPavel Dovgalyuk static bool intel_efer32_needed(void *opaque) 144189a44a10SPavel Dovgalyuk { 144289a44a10SPavel Dovgalyuk X86CPU *cpu = opaque; 144389a44a10SPavel Dovgalyuk CPUX86State *env = &cpu->env; 144489a44a10SPavel Dovgalyuk 144589a44a10SPavel Dovgalyuk return env->efer != 0; 144689a44a10SPavel Dovgalyuk } 144789a44a10SPavel Dovgalyuk 144889a44a10SPavel Dovgalyuk static const VMStateDescription vmstate_efer32 = { 144989a44a10SPavel Dovgalyuk .name = "cpu/efer32", 145089a44a10SPavel Dovgalyuk .version_id = 1, 145189a44a10SPavel Dovgalyuk .minimum_version_id = 1, 145289a44a10SPavel Dovgalyuk .needed = intel_efer32_needed, 1453c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 145489a44a10SPavel Dovgalyuk VMSTATE_UINT64(env.efer, X86CPU), 145589a44a10SPavel Dovgalyuk VMSTATE_END_OF_LIST() 145689a44a10SPavel Dovgalyuk } 145789a44a10SPavel Dovgalyuk }; 145889a44a10SPavel Dovgalyuk #endif 145989a44a10SPavel Dovgalyuk 14602a9758c5SPaolo Bonzini static bool msr_tsx_ctrl_needed(void *opaque) 14612a9758c5SPaolo Bonzini { 14622a9758c5SPaolo Bonzini X86CPU *cpu = opaque; 14632a9758c5SPaolo Bonzini CPUX86State *env = &cpu->env; 14642a9758c5SPaolo Bonzini 14652a9758c5SPaolo Bonzini return env->features[FEAT_ARCH_CAPABILITIES] & ARCH_CAP_TSX_CTRL_MSR; 14662a9758c5SPaolo Bonzini } 14672a9758c5SPaolo Bonzini 14682a9758c5SPaolo Bonzini static const VMStateDescription vmstate_msr_tsx_ctrl = { 14692a9758c5SPaolo Bonzini .name = "cpu/msr_tsx_ctrl", 14702a9758c5SPaolo Bonzini .version_id = 1, 14712a9758c5SPaolo Bonzini .minimum_version_id = 1, 14722a9758c5SPaolo Bonzini .needed = msr_tsx_ctrl_needed, 1473c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 14742a9758c5SPaolo Bonzini VMSTATE_UINT32(env.tsx_ctrl, X86CPU), 14752a9758c5SPaolo Bonzini VMSTATE_END_OF_LIST() 14762a9758c5SPaolo Bonzini } 14772a9758c5SPaolo Bonzini }; 14782a9758c5SPaolo Bonzini 1479db888065SSean Christopherson static bool intel_sgx_msrs_needed(void *opaque) 1480db888065SSean Christopherson { 1481db888065SSean Christopherson X86CPU *cpu = opaque; 1482db888065SSean Christopherson CPUX86State *env = &cpu->env; 1483db888065SSean Christopherson 1484db888065SSean Christopherson return !!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_SGX_LC); 1485db888065SSean Christopherson } 1486db888065SSean Christopherson 1487db888065SSean Christopherson static const VMStateDescription vmstate_msr_intel_sgx = { 1488db888065SSean Christopherson .name = "cpu/intel_sgx", 1489db888065SSean Christopherson .version_id = 1, 1490db888065SSean Christopherson .minimum_version_id = 1, 1491db888065SSean Christopherson .needed = intel_sgx_msrs_needed, 1492c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1493db888065SSean Christopherson VMSTATE_UINT64_ARRAY(env.msr_ia32_sgxlepubkeyhash, X86CPU, 4), 1494db888065SSean Christopherson VMSTATE_END_OF_LIST() 1495db888065SSean Christopherson } 1496db888065SSean Christopherson }; 1497db888065SSean Christopherson 14988f515d38SMaxim Levitsky static bool pdptrs_needed(void *opaque) 14998f515d38SMaxim Levitsky { 15008f515d38SMaxim Levitsky X86CPU *cpu = opaque; 15018f515d38SMaxim Levitsky CPUX86State *env = &cpu->env; 15028f515d38SMaxim Levitsky return env->pdptrs_valid; 15038f515d38SMaxim Levitsky } 15048f515d38SMaxim Levitsky 15058f515d38SMaxim Levitsky static int pdptrs_post_load(void *opaque, int version_id) 15068f515d38SMaxim Levitsky { 15078f515d38SMaxim Levitsky X86CPU *cpu = opaque; 15088f515d38SMaxim Levitsky CPUX86State *env = &cpu->env; 15098f515d38SMaxim Levitsky env->pdptrs_valid = true; 15108f515d38SMaxim Levitsky return 0; 15118f515d38SMaxim Levitsky } 15128f515d38SMaxim Levitsky 15138f515d38SMaxim Levitsky 15148f515d38SMaxim Levitsky static const VMStateDescription vmstate_pdptrs = { 15158f515d38SMaxim Levitsky .name = "cpu/pdptrs", 15168f515d38SMaxim Levitsky .version_id = 1, 15178f515d38SMaxim Levitsky .minimum_version_id = 1, 15188f515d38SMaxim Levitsky .needed = pdptrs_needed, 15198f515d38SMaxim Levitsky .post_load = pdptrs_post_load, 1520c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 15218f515d38SMaxim Levitsky VMSTATE_UINT64_ARRAY(env.pdptrs, X86CPU, 4), 15228f515d38SMaxim Levitsky VMSTATE_END_OF_LIST() 15238f515d38SMaxim Levitsky } 15248f515d38SMaxim Levitsky }; 15258f515d38SMaxim Levitsky 1526cdec2b75SZeng Guang static bool xfd_msrs_needed(void *opaque) 1527cdec2b75SZeng Guang { 1528cdec2b75SZeng Guang X86CPU *cpu = opaque; 1529cdec2b75SZeng Guang CPUX86State *env = &cpu->env; 1530cdec2b75SZeng Guang 1531cdec2b75SZeng Guang return !!(env->features[FEAT_XSAVE] & CPUID_D_1_EAX_XFD); 1532cdec2b75SZeng Guang } 1533cdec2b75SZeng Guang 1534cdec2b75SZeng Guang static const VMStateDescription vmstate_msr_xfd = { 1535cdec2b75SZeng Guang .name = "cpu/msr_xfd", 1536cdec2b75SZeng Guang .version_id = 1, 1537cdec2b75SZeng Guang .minimum_version_id = 1, 1538cdec2b75SZeng Guang .needed = xfd_msrs_needed, 1539c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1540cdec2b75SZeng Guang VMSTATE_UINT64(env.msr_xfd, X86CPU), 1541cdec2b75SZeng Guang VMSTATE_UINT64(env.msr_xfd_err, X86CPU), 1542cdec2b75SZeng Guang VMSTATE_END_OF_LIST() 1543cdec2b75SZeng Guang } 1544cdec2b75SZeng Guang }; 1545cdec2b75SZeng Guang 1546b5151aceSGao Shiyuan static bool msr_hwcr_needed(void *opaque) 1547b5151aceSGao Shiyuan { 1548b5151aceSGao Shiyuan X86CPU *cpu = opaque; 1549b5151aceSGao Shiyuan CPUX86State *env = &cpu->env; 1550b5151aceSGao Shiyuan 1551b5151aceSGao Shiyuan return env->msr_hwcr != 0; 1552b5151aceSGao Shiyuan } 1553b5151aceSGao Shiyuan 1554b5151aceSGao Shiyuan static const VMStateDescription vmstate_msr_hwcr = { 1555b5151aceSGao Shiyuan .name = "cpu/msr_hwcr", 1556b5151aceSGao Shiyuan .version_id = 1, 1557b5151aceSGao Shiyuan .minimum_version_id = 1, 1558b5151aceSGao Shiyuan .needed = msr_hwcr_needed, 1559b5151aceSGao Shiyuan .fields = (VMStateField[]) { 1560b5151aceSGao Shiyuan VMSTATE_UINT64(env.msr_hwcr, X86CPU), 1561b5151aceSGao Shiyuan VMSTATE_END_OF_LIST() 1562b5151aceSGao Shiyuan } 1563b5151aceSGao Shiyuan }; 1564b5151aceSGao Shiyuan 1565cdec2b75SZeng Guang #ifdef TARGET_X86_64 15664ebd98ebSXin Li static bool intel_fred_msrs_needed(void *opaque) 15674ebd98ebSXin Li { 15684ebd98ebSXin Li X86CPU *cpu = opaque; 15694ebd98ebSXin Li CPUX86State *env = &cpu->env; 15704ebd98ebSXin Li 15714ebd98ebSXin Li return !!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_FRED); 15724ebd98ebSXin Li } 15734ebd98ebSXin Li 15744ebd98ebSXin Li static const VMStateDescription vmstate_msr_fred = { 15754ebd98ebSXin Li .name = "cpu/fred", 15764ebd98ebSXin Li .version_id = 1, 15774ebd98ebSXin Li .minimum_version_id = 1, 15784ebd98ebSXin Li .needed = intel_fred_msrs_needed, 15794ebd98ebSXin Li .fields = (VMStateField[]) { 15804ebd98ebSXin Li VMSTATE_UINT64(env.fred_rsp0, X86CPU), 15814ebd98ebSXin Li VMSTATE_UINT64(env.fred_rsp1, X86CPU), 15824ebd98ebSXin Li VMSTATE_UINT64(env.fred_rsp2, X86CPU), 15834ebd98ebSXin Li VMSTATE_UINT64(env.fred_rsp3, X86CPU), 15844ebd98ebSXin Li VMSTATE_UINT64(env.fred_stklvls, X86CPU), 15854ebd98ebSXin Li VMSTATE_UINT64(env.fred_ssp1, X86CPU), 15864ebd98ebSXin Li VMSTATE_UINT64(env.fred_ssp2, X86CPU), 15874ebd98ebSXin Li VMSTATE_UINT64(env.fred_ssp3, X86CPU), 15884ebd98ebSXin Li VMSTATE_UINT64(env.fred_config, X86CPU), 15894ebd98ebSXin Li VMSTATE_END_OF_LIST() 15904ebd98ebSXin Li } 15914ebd98ebSXin Li }; 15924ebd98ebSXin Li 1593cdec2b75SZeng Guang static bool amx_xtile_needed(void *opaque) 1594cdec2b75SZeng Guang { 1595cdec2b75SZeng Guang X86CPU *cpu = opaque; 1596cdec2b75SZeng Guang CPUX86State *env = &cpu->env; 1597cdec2b75SZeng Guang 1598cdec2b75SZeng Guang return !!(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_AMX_TILE); 1599cdec2b75SZeng Guang } 1600cdec2b75SZeng Guang 1601cdec2b75SZeng Guang static const VMStateDescription vmstate_amx_xtile = { 1602cdec2b75SZeng Guang .name = "cpu/intel_amx_xtile", 1603cdec2b75SZeng Guang .version_id = 1, 1604cdec2b75SZeng Guang .minimum_version_id = 1, 1605cdec2b75SZeng Guang .needed = amx_xtile_needed, 1606c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1607cdec2b75SZeng Guang VMSTATE_UINT8_ARRAY(env.xtilecfg, X86CPU, 64), 1608cdec2b75SZeng Guang VMSTATE_UINT8_ARRAY(env.xtiledata, X86CPU, 8192), 1609cdec2b75SZeng Guang VMSTATE_END_OF_LIST() 1610cdec2b75SZeng Guang } 1611cdec2b75SZeng Guang }; 1612cdec2b75SZeng Guang #endif 1613cdec2b75SZeng Guang 1614f2e7c2fcSYang Weijiang static bool arch_lbr_needed(void *opaque) 1615f2e7c2fcSYang Weijiang { 1616f2e7c2fcSYang Weijiang X86CPU *cpu = opaque; 1617f2e7c2fcSYang Weijiang CPUX86State *env = &cpu->env; 1618f2e7c2fcSYang Weijiang 1619f2e7c2fcSYang Weijiang return !!(env->features[FEAT_7_0_EDX] & CPUID_7_0_EDX_ARCH_LBR); 1620f2e7c2fcSYang Weijiang } 1621f2e7c2fcSYang Weijiang 1622f2e7c2fcSYang Weijiang static const VMStateDescription vmstate_arch_lbr = { 1623f2e7c2fcSYang Weijiang .name = "cpu/arch_lbr", 1624f2e7c2fcSYang Weijiang .version_id = 1, 1625f2e7c2fcSYang Weijiang .minimum_version_id = 1, 1626f2e7c2fcSYang Weijiang .needed = arch_lbr_needed, 1627c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1628f2e7c2fcSYang Weijiang VMSTATE_UINT64(env.msr_lbr_ctl, X86CPU), 1629f2e7c2fcSYang Weijiang VMSTATE_UINT64(env.msr_lbr_depth, X86CPU), 1630f2e7c2fcSYang Weijiang VMSTATE_LBR_VARS(env.lbr_records, X86CPU, ARCH_LBR_NR_ENTRIES, 1), 1631f2e7c2fcSYang Weijiang VMSTATE_END_OF_LIST() 1632f2e7c2fcSYang Weijiang } 1633f2e7c2fcSYang Weijiang }; 1634f2e7c2fcSYang Weijiang 163512f89a39SChenyi Qiang static bool triple_fault_needed(void *opaque) 163612f89a39SChenyi Qiang { 163712f89a39SChenyi Qiang X86CPU *cpu = opaque; 163812f89a39SChenyi Qiang CPUX86State *env = &cpu->env; 163912f89a39SChenyi Qiang 164012f89a39SChenyi Qiang return env->triple_fault_pending; 164112f89a39SChenyi Qiang } 164212f89a39SChenyi Qiang 164312f89a39SChenyi Qiang static const VMStateDescription vmstate_triple_fault = { 164412f89a39SChenyi Qiang .name = "cpu/triple_fault", 164512f89a39SChenyi Qiang .version_id = 1, 164612f89a39SChenyi Qiang .minimum_version_id = 1, 164712f89a39SChenyi Qiang .needed = triple_fault_needed, 1648c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 164912f89a39SChenyi Qiang VMSTATE_UINT8(env.triple_fault_pending, X86CPU), 165012f89a39SChenyi Qiang VMSTATE_END_OF_LIST() 165112f89a39SChenyi Qiang } 165212f89a39SChenyi Qiang }; 165312f89a39SChenyi Qiang 1654ac701a4fSKeqian Zhu const VMStateDescription vmstate_x86_cpu = { 16550cb892aaSJuan Quintela .name = "cpu", 1656f56e3a14SAndreas Färber .version_id = 12, 165708b277acSDr. David Alan Gilbert .minimum_version_id = 11, 16580cb892aaSJuan Quintela .pre_save = cpu_pre_save, 16590cb892aaSJuan Quintela .post_load = cpu_post_load, 1660c4f54bd6SRichard Henderson .fields = (const VMStateField[]) { 1661f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS), 1662f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eip, X86CPU), 1663f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eflags, X86CPU), 1664f56e3a14SAndreas Färber VMSTATE_UINT32(env.hflags, X86CPU), 16650cb892aaSJuan Quintela /* FPU */ 1666f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpuc, X86CPU), 1667f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpus_vmstate, X86CPU), 1668f56e3a14SAndreas Färber VMSTATE_UINT16(env.fptag_vmstate, X86CPU), 1669f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU), 167046baa900SDr. David Alan Gilbert 167146baa900SDr. David Alan Gilbert VMSTATE_STRUCT_ARRAY(env.fpregs, X86CPU, 8, 0, vmstate_fpreg, FPReg), 16728dd3dca3Saurel32 1673f56e3a14SAndreas Färber VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6), 1674f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.ldt, X86CPU), 1675f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.tr, X86CPU), 1676f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.gdt, X86CPU), 1677f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.idt, X86CPU), 1678468f6581SJuan Quintela 1679f56e3a14SAndreas Färber VMSTATE_UINT32(env.sysenter_cs, X86CPU), 1680f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_esp, X86CPU), 1681f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_eip, X86CPU), 16828dd3dca3Saurel32 1683f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[0], X86CPU), 1684f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[2], X86CPU), 1685f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[3], X86CPU), 1686f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[4], X86CPU), 1687f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8), 16880cb892aaSJuan Quintela /* MMU */ 1689f56e3a14SAndreas Färber VMSTATE_INT32(env.a20_mask, X86CPU), 16900cb892aaSJuan Quintela /* XMM */ 1691f56e3a14SAndreas Färber VMSTATE_UINT32(env.mxcsr, X86CPU), 1692a03c3e90SPaolo Bonzini VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, 0), 16938dd3dca3Saurel32 16948dd3dca3Saurel32 #ifdef TARGET_X86_64 1695f56e3a14SAndreas Färber VMSTATE_UINT64(env.efer, X86CPU), 1696f56e3a14SAndreas Färber VMSTATE_UINT64(env.star, X86CPU), 1697f56e3a14SAndreas Färber VMSTATE_UINT64(env.lstar, X86CPU), 1698f56e3a14SAndreas Färber VMSTATE_UINT64(env.cstar, X86CPU), 1699f56e3a14SAndreas Färber VMSTATE_UINT64(env.fmask, X86CPU), 1700f56e3a14SAndreas Färber VMSTATE_UINT64(env.kernelgsbase, X86CPU), 17018dd3dca3Saurel32 #endif 170208b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.smbase, X86CPU), 17038dd3dca3Saurel32 170408b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.pat, X86CPU), 170508b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.hflags2, X86CPU), 1706dd5e3b17Saliguori 170708b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.vm_hsave, X86CPU), 170808b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.vm_vmcb, X86CPU), 170908b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.tsc_offset, X86CPU), 171008b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.intercept, X86CPU), 171108b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_cr_read, X86CPU), 171208b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_cr_write, X86CPU), 171308b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_dr_read, X86CPU), 171408b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_dr_write, X86CPU), 171508b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.intercept_exceptions, X86CPU), 171608b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.v_tpr, X86CPU), 1717dd5e3b17Saliguori /* MTRRs */ 171808b277acSDr. David Alan Gilbert VMSTATE_UINT64_ARRAY(env.mtrr_fixed, X86CPU, 11), 171908b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mtrr_deftype, X86CPU), 1720d8b5c67bSAlex Williamson VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, MSR_MTRRcap_VCNT, 8), 17210cb892aaSJuan Quintela /* KVM-related states */ 172208b277acSDr. David Alan Gilbert VMSTATE_INT32(env.interrupt_injected, X86CPU), 172308b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.mp_state, X86CPU), 172408b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.tsc, X86CPU), 1725fd13f23bSLiran Alon VMSTATE_INT32(env.exception_nr, X86CPU), 172608b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.soft_interrupt, X86CPU), 172708b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.nmi_injected, X86CPU), 172808b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.nmi_pending, X86CPU), 172908b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.has_error_code, X86CPU), 173008b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.sipi_vector, X86CPU), 17310cb892aaSJuan Quintela /* MCE */ 173208b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mcg_cap, X86CPU), 173308b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mcg_status, X86CPU), 173408b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mcg_ctl, X86CPU), 173508b277acSDr. David Alan Gilbert VMSTATE_UINT64_ARRAY(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4), 17360cb892aaSJuan Quintela /* rdtscp */ 173708b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.tsc_aux, X86CPU), 17381a03675dSGlauber Costa /* KVM pvclock msr */ 173908b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.system_time_msr, X86CPU), 174008b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.wall_clock_msr, X86CPU), 1741f1665b21SSheng Yang /* XSAVE related fields */ 1742f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xcr0, X86CPU, 12), 1743f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12), 1744b7711471SPaolo Bonzini VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, 0, 12), 17450cb892aaSJuan Quintela VMSTATE_END_OF_LIST() 1746a0fb002cSJan Kiszka /* The above list is not sorted /wrt version numbers, watch out! */ 1747f6584ee2SGleb Natapov }, 1748c4f54bd6SRichard Henderson .subsections = (const VMStateDescription * const []) { 1749fd13f23bSLiran Alon &vmstate_exception_info, 17505cd8cadaSJuan Quintela &vmstate_async_pf_msr, 1751db5daafaSVitaly Kuznetsov &vmstate_async_pf_int_msr, 17525cd8cadaSJuan Quintela &vmstate_pv_eoi_msr, 17535cd8cadaSJuan Quintela &vmstate_steal_time_msr, 1754d645e132SMarcelo Tosatti &vmstate_poll_control_msr, 17555cd8cadaSJuan Quintela &vmstate_fpop_ip_dp, 17565cd8cadaSJuan Quintela &vmstate_msr_tsc_adjust, 17575cd8cadaSJuan Quintela &vmstate_msr_tscdeadline, 17585cd8cadaSJuan Quintela &vmstate_msr_ia32_misc_enable, 17595cd8cadaSJuan Quintela &vmstate_msr_ia32_feature_control, 17605cd8cadaSJuan Quintela &vmstate_msr_architectural_pmu, 17615cd8cadaSJuan Quintela &vmstate_mpx, 1762816d20c9SVitaly Kuznetsov &vmstate_msr_hyperv_hypercall, 17635cd8cadaSJuan Quintela &vmstate_msr_hyperv_vapic, 17645cd8cadaSJuan Quintela &vmstate_msr_hyperv_time, 1765f2a53c9eSAndrey Smetanin &vmstate_msr_hyperv_crash, 176646eb8f98SAndrey Smetanin &vmstate_msr_hyperv_runtime, 1767866eea9aSAndrey Smetanin &vmstate_msr_hyperv_synic, 1768ff99aa64SAndrey Smetanin &vmstate_msr_hyperv_stimer, 1769ba6a4fd9SVitaly Kuznetsov &vmstate_msr_hyperv_reenlightenment, 17705cd8cadaSJuan Quintela &vmstate_avx512, 17715cd8cadaSJuan Quintela &vmstate_xss, 177265087997STao Xu &vmstate_umwait, 177336f96c4bSHaozhong Zhang &vmstate_tsc_khz, 1774e13713dbSLiran Alon &vmstate_msr_smi_count, 1775f74eefe0SHuaitong Han &vmstate_pkru, 1776e7e7bdabSPaolo Bonzini &vmstate_pkrs, 1777a33a2cfeSPaolo Bonzini &vmstate_spec_ctrl, 1778cabf9862SMaxim Levitsky &amd_tsc_scale_msr_ctrl, 177987f8b626SAshok Raj &vmstate_mcg_ext_ctl, 1780b77146e9SChao Peng &vmstate_msr_intel_pt, 1781cfeea0c0SKonrad Rzeszutek Wilk &vmstate_msr_virt_ssbd, 1782fe441054SJan Kiszka &vmstate_svm_npt, 1783e3126a5cSLara Lazier &vmstate_svm_guest, 178489a44a10SPavel Dovgalyuk #ifndef TARGET_X86_64 178589a44a10SPavel Dovgalyuk &vmstate_efer32, 178689a44a10SPavel Dovgalyuk #endif 1787ebbfef2fSLiran Alon #ifdef CONFIG_KVM 1788ebbfef2fSLiran Alon &vmstate_nested_state, 1789c345104cSJoao Martins &vmstate_xen_vcpu, 1790ebbfef2fSLiran Alon #endif 17912a9758c5SPaolo Bonzini &vmstate_msr_tsx_ctrl, 1792db888065SSean Christopherson &vmstate_msr_intel_sgx, 17938f515d38SMaxim Levitsky &vmstate_pdptrs, 1794cdec2b75SZeng Guang &vmstate_msr_xfd, 1795b5151aceSGao Shiyuan &vmstate_msr_hwcr, 1796cdec2b75SZeng Guang #ifdef TARGET_X86_64 17974ebd98ebSXin Li &vmstate_msr_fred, 1798cdec2b75SZeng Guang &vmstate_amx_xtile, 1799cdec2b75SZeng Guang #endif 1800f2e7c2fcSYang Weijiang &vmstate_arch_lbr, 180112f89a39SChenyi Qiang &vmstate_triple_fault, 18025cd8cadaSJuan Quintela NULL 1803dd5e3b17Saliguori } 18040cb892aaSJuan Quintela }; 1805