1b6a0aa05SPeter Maydell #include "qemu/osdep.h" 233c11879SPaolo Bonzini #include "cpu.h" 363c91552SPaolo Bonzini #include "exec/exec-all.h" 40d09e41aSPaolo Bonzini #include "hw/isa/isa.h" 51e00b8d5SPaolo Bonzini #include "migration/cpu.h" 6*a9dc68d9SClaudio Fontana #include "kvm/hyperv.h" 789a289c7SPaolo Bonzini #include "hw/i386/x86.h" 8*a9dc68d9SClaudio Fontana #include "kvm/kvm_i386.h" 98dd3dca3Saurel32 109c17d615SPaolo Bonzini #include "sysemu/kvm.h" 1114a48c1dSMarkus Armbruster #include "sysemu/tcg.h" 128dd3dca3Saurel32 1336f96c4bSHaozhong Zhang #include "qemu/error-report.h" 1436f96c4bSHaozhong Zhang 1566e6d55bSJuan Quintela static const VMStateDescription vmstate_segment = { 1666e6d55bSJuan Quintela .name = "segment", 1766e6d55bSJuan Quintela .version_id = 1, 1866e6d55bSJuan Quintela .minimum_version_id = 1, 1966e6d55bSJuan Quintela .fields = (VMStateField[]) { 2066e6d55bSJuan Quintela VMSTATE_UINT32(selector, SegmentCache), 2166e6d55bSJuan Quintela VMSTATE_UINTTL(base, SegmentCache), 2266e6d55bSJuan Quintela VMSTATE_UINT32(limit, SegmentCache), 2366e6d55bSJuan Quintela VMSTATE_UINT32(flags, SegmentCache), 2466e6d55bSJuan Quintela VMSTATE_END_OF_LIST() 2566e6d55bSJuan Quintela } 2666e6d55bSJuan Quintela }; 2766e6d55bSJuan Quintela 280cb892aaSJuan Quintela #define VMSTATE_SEGMENT(_field, _state) { \ 290cb892aaSJuan Quintela .name = (stringify(_field)), \ 300cb892aaSJuan Quintela .size = sizeof(SegmentCache), \ 310cb892aaSJuan Quintela .vmsd = &vmstate_segment, \ 320cb892aaSJuan Quintela .flags = VMS_STRUCT, \ 330cb892aaSJuan Quintela .offset = offsetof(_state, _field) \ 340cb892aaSJuan Quintela + type_check(SegmentCache,typeof_field(_state, _field)) \ 358dd3dca3Saurel32 } 368dd3dca3Saurel32 370cb892aaSJuan Quintela #define VMSTATE_SEGMENT_ARRAY(_field, _state, _n) \ 380cb892aaSJuan Quintela VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_segment, SegmentCache) 398dd3dca3Saurel32 40fc3b0aa2SJuan Quintela static const VMStateDescription vmstate_xmm_reg = { 41fc3b0aa2SJuan Quintela .name = "xmm_reg", 42fc3b0aa2SJuan Quintela .version_id = 1, 43fc3b0aa2SJuan Quintela .minimum_version_id = 1, 44fc3b0aa2SJuan Quintela .fields = (VMStateField[]) { 4519cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(0), ZMMReg), 4619cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(1), ZMMReg), 47fc3b0aa2SJuan Quintela VMSTATE_END_OF_LIST() 48fc3b0aa2SJuan Quintela } 49fc3b0aa2SJuan Quintela }; 50fc3b0aa2SJuan Quintela 51a03c3e90SPaolo Bonzini #define VMSTATE_XMM_REGS(_field, _state, _start) \ 52a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 53fa451874SEduardo Habkost vmstate_xmm_reg, ZMMReg) 54fc3b0aa2SJuan Quintela 55b7711471SPaolo Bonzini /* YMMH format is the same as XMM, but for bits 128-255 */ 56f1665b21SSheng Yang static const VMStateDescription vmstate_ymmh_reg = { 57f1665b21SSheng Yang .name = "ymmh_reg", 58f1665b21SSheng Yang .version_id = 1, 59f1665b21SSheng Yang .minimum_version_id = 1, 60f1665b21SSheng Yang .fields = (VMStateField[]) { 6119cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(2), ZMMReg), 6219cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(3), ZMMReg), 63f1665b21SSheng Yang VMSTATE_END_OF_LIST() 64f1665b21SSheng Yang } 65f1665b21SSheng Yang }; 66f1665b21SSheng Yang 67a03c3e90SPaolo Bonzini #define VMSTATE_YMMH_REGS_VARS(_field, _state, _start, _v) \ 68a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, _v, \ 69fa451874SEduardo Habkost vmstate_ymmh_reg, ZMMReg) 70f1665b21SSheng Yang 719aecd6f8SChao Peng static const VMStateDescription vmstate_zmmh_reg = { 729aecd6f8SChao Peng .name = "zmmh_reg", 739aecd6f8SChao Peng .version_id = 1, 749aecd6f8SChao Peng .minimum_version_id = 1, 759aecd6f8SChao Peng .fields = (VMStateField[]) { 7619cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(4), ZMMReg), 7719cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(5), ZMMReg), 7819cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(6), ZMMReg), 7919cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(7), ZMMReg), 809aecd6f8SChao Peng VMSTATE_END_OF_LIST() 819aecd6f8SChao Peng } 829aecd6f8SChao Peng }; 839aecd6f8SChao Peng 84a03c3e90SPaolo Bonzini #define VMSTATE_ZMMH_REGS_VARS(_field, _state, _start) \ 85a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 86fa451874SEduardo Habkost vmstate_zmmh_reg, ZMMReg) 879aecd6f8SChao Peng 889aecd6f8SChao Peng #ifdef TARGET_X86_64 899aecd6f8SChao Peng static const VMStateDescription vmstate_hi16_zmm_reg = { 909aecd6f8SChao Peng .name = "hi16_zmm_reg", 919aecd6f8SChao Peng .version_id = 1, 929aecd6f8SChao Peng .minimum_version_id = 1, 939aecd6f8SChao Peng .fields = (VMStateField[]) { 9419cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(0), ZMMReg), 9519cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(1), ZMMReg), 9619cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(2), ZMMReg), 9719cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(3), ZMMReg), 9819cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(4), ZMMReg), 9919cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(5), ZMMReg), 10019cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(6), ZMMReg), 10119cbd87cSEduardo Habkost VMSTATE_UINT64(ZMM_Q(7), ZMMReg), 1029aecd6f8SChao Peng VMSTATE_END_OF_LIST() 1039aecd6f8SChao Peng } 1049aecd6f8SChao Peng }; 1059aecd6f8SChao Peng 106a03c3e90SPaolo Bonzini #define VMSTATE_Hi16_ZMM_REGS_VARS(_field, _state, _start) \ 107a03c3e90SPaolo Bonzini VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0, \ 108fa451874SEduardo Habkost vmstate_hi16_zmm_reg, ZMMReg) 1099aecd6f8SChao Peng #endif 1109aecd6f8SChao Peng 11179e9ebebSLiu Jinsong static const VMStateDescription vmstate_bnd_regs = { 11279e9ebebSLiu Jinsong .name = "bnd_regs", 11379e9ebebSLiu Jinsong .version_id = 1, 11479e9ebebSLiu Jinsong .minimum_version_id = 1, 11579e9ebebSLiu Jinsong .fields = (VMStateField[]) { 11679e9ebebSLiu Jinsong VMSTATE_UINT64(lb, BNDReg), 11779e9ebebSLiu Jinsong VMSTATE_UINT64(ub, BNDReg), 11879e9ebebSLiu Jinsong VMSTATE_END_OF_LIST() 11979e9ebebSLiu Jinsong } 12079e9ebebSLiu Jinsong }; 12179e9ebebSLiu Jinsong 12279e9ebebSLiu Jinsong #define VMSTATE_BND_REGS(_field, _state, _n) \ 12379e9ebebSLiu Jinsong VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_bnd_regs, BNDReg) 12479e9ebebSLiu Jinsong 125216c07c3SJuan Quintela static const VMStateDescription vmstate_mtrr_var = { 126216c07c3SJuan Quintela .name = "mtrr_var", 127216c07c3SJuan Quintela .version_id = 1, 128216c07c3SJuan Quintela .minimum_version_id = 1, 129216c07c3SJuan Quintela .fields = (VMStateField[]) { 130216c07c3SJuan Quintela VMSTATE_UINT64(base, MTRRVar), 131216c07c3SJuan Quintela VMSTATE_UINT64(mask, MTRRVar), 132216c07c3SJuan Quintela VMSTATE_END_OF_LIST() 133216c07c3SJuan Quintela } 134216c07c3SJuan Quintela }; 135216c07c3SJuan Quintela 1360cb892aaSJuan Quintela #define VMSTATE_MTRR_VARS(_field, _state, _n, _v) \ 1370cb892aaSJuan Quintela VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar) 138216c07c3SJuan Quintela 139ab808276SDr. David Alan Gilbert typedef struct x86_FPReg_tmp { 140ab808276SDr. David Alan Gilbert FPReg *parent; 141ab808276SDr. David Alan Gilbert uint64_t tmp_mant; 142ab808276SDr. David Alan Gilbert uint16_t tmp_exp; 143ab808276SDr. David Alan Gilbert } x86_FPReg_tmp; 1443c8ce630SJuan Quintela 145db573d2cSYang Zhong static void cpu_get_fp80(uint64_t *pmant, uint16_t *pexp, floatx80 f) 146db573d2cSYang Zhong { 147db573d2cSYang Zhong CPU_LDoubleU temp; 148db573d2cSYang Zhong 149db573d2cSYang Zhong temp.d = f; 150db573d2cSYang Zhong *pmant = temp.l.lower; 151db573d2cSYang Zhong *pexp = temp.l.upper; 152db573d2cSYang Zhong } 153db573d2cSYang Zhong 154db573d2cSYang Zhong static floatx80 cpu_set_fp80(uint64_t mant, uint16_t upper) 155db573d2cSYang Zhong { 156db573d2cSYang Zhong CPU_LDoubleU temp; 157db573d2cSYang Zhong 158db573d2cSYang Zhong temp.l.upper = upper; 159db573d2cSYang Zhong temp.l.lower = mant; 160db573d2cSYang Zhong return temp.d; 161db573d2cSYang Zhong } 162db573d2cSYang Zhong 16344b1ff31SDr. David Alan Gilbert static int fpreg_pre_save(void *opaque) 1643c8ce630SJuan Quintela { 165ab808276SDr. David Alan Gilbert x86_FPReg_tmp *tmp = opaque; 166ab808276SDr. David Alan Gilbert 1673c8ce630SJuan Quintela /* we save the real CPU data (in case of MMX usage only 'mant' 1683c8ce630SJuan Quintela contains the MMX register */ 169ab808276SDr. David Alan Gilbert cpu_get_fp80(&tmp->tmp_mant, &tmp->tmp_exp, tmp->parent->d); 17044b1ff31SDr. David Alan Gilbert 17144b1ff31SDr. David Alan Gilbert return 0; 172ab808276SDr. David Alan Gilbert } 1732c21ee76SJianjun Duan 174ab808276SDr. David Alan Gilbert static int fpreg_post_load(void *opaque, int version) 175ab808276SDr. David Alan Gilbert { 176ab808276SDr. David Alan Gilbert x86_FPReg_tmp *tmp = opaque; 177ab808276SDr. David Alan Gilbert 178ab808276SDr. David Alan Gilbert tmp->parent->d = cpu_set_fp80(tmp->tmp_mant, tmp->tmp_exp); 1792c21ee76SJianjun Duan return 0; 1803c8ce630SJuan Quintela } 1813c8ce630SJuan Quintela 182ab808276SDr. David Alan Gilbert static const VMStateDescription vmstate_fpreg_tmp = { 183ab808276SDr. David Alan Gilbert .name = "fpreg_tmp", 184ab808276SDr. David Alan Gilbert .post_load = fpreg_post_load, 185ab808276SDr. David Alan Gilbert .pre_save = fpreg_pre_save, 186ab808276SDr. David Alan Gilbert .fields = (VMStateField[]) { 187ab808276SDr. David Alan Gilbert VMSTATE_UINT64(tmp_mant, x86_FPReg_tmp), 188ab808276SDr. David Alan Gilbert VMSTATE_UINT16(tmp_exp, x86_FPReg_tmp), 189ab808276SDr. David Alan Gilbert VMSTATE_END_OF_LIST() 190ab808276SDr. David Alan Gilbert } 191ab808276SDr. David Alan Gilbert }; 192ab808276SDr. David Alan Gilbert 193ab808276SDr. David Alan Gilbert static const VMStateDescription vmstate_fpreg = { 1940cb892aaSJuan Quintela .name = "fpreg", 195ab808276SDr. David Alan Gilbert .fields = (VMStateField[]) { 196ab808276SDr. David Alan Gilbert VMSTATE_WITH_TMP(FPReg, x86_FPReg_tmp, vmstate_fpreg_tmp), 197ab808276SDr. David Alan Gilbert VMSTATE_END_OF_LIST() 198ab808276SDr. David Alan Gilbert } 1990cb892aaSJuan Quintela }; 2000cb892aaSJuan Quintela 20144b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque) 2028dd3dca3Saurel32 { 203f56e3a14SAndreas Färber X86CPU *cpu = opaque; 204f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 2050e607a80SJan Kiszka int i; 2068dd3dca3Saurel32 2078dd3dca3Saurel32 /* FPU */ 20867b8f419SJuan Quintela env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; 209cdc0c58fSJuan Quintela env->fptag_vmstate = 0; 2108dd3dca3Saurel32 for(i = 0; i < 8; i++) { 211cdc0c58fSJuan Quintela env->fptag_vmstate |= ((!env->fptags[i]) << i); 2128dd3dca3Saurel32 } 2138dd3dca3Saurel32 21460a902f1SJuan Quintela env->fpregs_format_vmstate = 0; 2153e47c249SOrit Wasserman 2163e47c249SOrit Wasserman /* 2173e47c249SOrit Wasserman * Real mode guest segments register DPL should be zero. 2183e47c249SOrit Wasserman * Older KVM version were setting it wrongly. 2193e47c249SOrit Wasserman * Fixing it will allow live migration to host with unrestricted guest 2203e47c249SOrit Wasserman * support (otherwise the migration will fail with invalid guest state 2213e47c249SOrit Wasserman * error). 2223e47c249SOrit Wasserman */ 2233e47c249SOrit Wasserman if (!(env->cr[0] & CR0_PE_MASK) && 2243e47c249SOrit Wasserman (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { 2253e47c249SOrit Wasserman env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); 2263e47c249SOrit Wasserman env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); 2273e47c249SOrit Wasserman env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); 2283e47c249SOrit Wasserman env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); 2293e47c249SOrit Wasserman env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); 2303e47c249SOrit Wasserman env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); 2313e47c249SOrit Wasserman } 2323e47c249SOrit Wasserman 233ebbfef2fSLiran Alon #ifdef CONFIG_KVM 23479a197abSLiran Alon /* 23579a197abSLiran Alon * In case vCPU may have enabled VMX, we need to make sure kernel have 23679a197abSLiran Alon * required capabilities in order to perform migration correctly: 23779a197abSLiran Alon * 23879a197abSLiran Alon * 1) We must be able to extract vCPU nested-state from KVM. 23979a197abSLiran Alon * 24079a197abSLiran Alon * 2) In case vCPU is running in guest-mode and it has a pending exception, 24179a197abSLiran Alon * we must be able to determine if it's in a pending or injected state. 24279a197abSLiran Alon * Note that in case KVM don't have required capability to do so, 24379a197abSLiran Alon * a pending/injected exception will always appear as an 24479a197abSLiran Alon * injected exception. 24579a197abSLiran Alon */ 24679a197abSLiran Alon if (kvm_enabled() && cpu_vmx_maybe_enabled(env) && 24779a197abSLiran Alon (!env->nested_state || 24879a197abSLiran Alon (!kvm_has_exception_payload() && (env->hflags & HF_GUEST_MASK) && 24979a197abSLiran Alon env->exception_injected))) { 25079a197abSLiran Alon error_report("Guest maybe enabled nested virtualization but kernel " 25179a197abSLiran Alon "does not support required capabilities to save vCPU " 25279a197abSLiran Alon "nested state"); 253ebbfef2fSLiran Alon return -EINVAL; 254ebbfef2fSLiran Alon } 255ebbfef2fSLiran Alon #endif 256ebbfef2fSLiran Alon 257fd13f23bSLiran Alon /* 258fd13f23bSLiran Alon * When vCPU is running L2 and exception is still pending, 259fd13f23bSLiran Alon * it can potentially be intercepted by L1 hypervisor. 260fd13f23bSLiran Alon * In contrast to an injected exception which cannot be 261fd13f23bSLiran Alon * intercepted anymore. 262fd13f23bSLiran Alon * 263fd13f23bSLiran Alon * Furthermore, when a L2 exception is intercepted by L1 2647332a4a4SCameron Esfahani * hypervisor, its exception payload (CR2/DR6 on #PF/#DB) 265fd13f23bSLiran Alon * should not be set yet in the respective vCPU register. 266fd13f23bSLiran Alon * Thus, in case an exception is pending, it is 267fd13f23bSLiran Alon * important to save the exception payload seperately. 268fd13f23bSLiran Alon * 269fd13f23bSLiran Alon * Therefore, if an exception is not in a pending state 270fd13f23bSLiran Alon * or vCPU is not in guest-mode, it is not important to 271fd13f23bSLiran Alon * distinguish between a pending and injected exception 272fd13f23bSLiran Alon * and we don't need to store seperately the exception payload. 273fd13f23bSLiran Alon * 2747332a4a4SCameron Esfahani * In order to preserve better backwards-compatible migration, 275fd13f23bSLiran Alon * convert a pending exception to an injected exception in 2767332a4a4SCameron Esfahani * case it is not important to distinguish between them 277fd13f23bSLiran Alon * as described above. 278fd13f23bSLiran Alon */ 279fd13f23bSLiran Alon if (env->exception_pending && !(env->hflags & HF_GUEST_MASK)) { 280fd13f23bSLiran Alon env->exception_pending = 0; 281fd13f23bSLiran Alon env->exception_injected = 1; 282fd13f23bSLiran Alon 283fd13f23bSLiran Alon if (env->exception_has_payload) { 284fd13f23bSLiran Alon if (env->exception_nr == EXCP01_DB) { 285fd13f23bSLiran Alon env->dr[6] = env->exception_payload; 286fd13f23bSLiran Alon } else if (env->exception_nr == EXCP0E_PAGE) { 287fd13f23bSLiran Alon env->cr[2] = env->exception_payload; 288fd13f23bSLiran Alon } 289fd13f23bSLiran Alon } 290fd13f23bSLiran Alon } 291fd13f23bSLiran Alon 29244b1ff31SDr. David Alan Gilbert return 0; 293c4c38c8cSJuan Quintela } 294c4c38c8cSJuan Quintela 295468f6581SJuan Quintela static int cpu_post_load(void *opaque, int version_id) 296468f6581SJuan Quintela { 297f56e3a14SAndreas Färber X86CPU *cpu = opaque; 29875a34036SAndreas Färber CPUState *cs = CPU(cpu); 299f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 300468f6581SJuan Quintela int i; 301468f6581SJuan Quintela 30236f96c4bSHaozhong Zhang if (env->tsc_khz && env->user_tsc_khz && 30336f96c4bSHaozhong Zhang env->tsc_khz != env->user_tsc_khz) { 30436f96c4bSHaozhong Zhang error_report("Mismatch between user-specified TSC frequency and " 30536f96c4bSHaozhong Zhang "migrated TSC frequency"); 30636f96c4bSHaozhong Zhang return -EINVAL; 30736f96c4bSHaozhong Zhang } 30836f96c4bSHaozhong Zhang 30946baa900SDr. David Alan Gilbert if (env->fpregs_format_vmstate) { 31046baa900SDr. David Alan Gilbert error_report("Unsupported old non-softfloat CPU state"); 31146baa900SDr. David Alan Gilbert return -EINVAL; 31246baa900SDr. David Alan Gilbert } 313444ba679SOrit Wasserman /* 314444ba679SOrit Wasserman * Real mode guest segments register DPL should be zero. 315444ba679SOrit Wasserman * Older KVM version were setting it wrongly. 316444ba679SOrit Wasserman * Fixing it will allow live migration from such host that don't have 317444ba679SOrit Wasserman * restricted guest support to a host with unrestricted guest support 318444ba679SOrit Wasserman * (otherwise the migration will fail with invalid guest state 319444ba679SOrit Wasserman * error). 320444ba679SOrit Wasserman */ 321444ba679SOrit Wasserman if (!(env->cr[0] & CR0_PE_MASK) && 322444ba679SOrit Wasserman (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) { 323444ba679SOrit Wasserman env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK); 324444ba679SOrit Wasserman env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK); 325444ba679SOrit Wasserman env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK); 326444ba679SOrit Wasserman env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK); 327444ba679SOrit Wasserman env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK); 328444ba679SOrit Wasserman env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK); 329444ba679SOrit Wasserman } 330444ba679SOrit Wasserman 3317125c937SPaolo Bonzini /* Older versions of QEMU incorrectly used CS.DPL as the CPL when 3327125c937SPaolo Bonzini * running under KVM. This is wrong for conforming code segments. 3337125c937SPaolo Bonzini * Luckily, in our implementation the CPL field of hflags is redundant 3347125c937SPaolo Bonzini * and we can get the right value from the SS descriptor privilege level. 3357125c937SPaolo Bonzini */ 3367125c937SPaolo Bonzini env->hflags &= ~HF_CPL_MASK; 3377125c937SPaolo Bonzini env->hflags |= (env->segs[R_SS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK; 3387125c937SPaolo Bonzini 339ebbfef2fSLiran Alon #ifdef CONFIG_KVM 340ebbfef2fSLiran Alon if ((env->hflags & HF_GUEST_MASK) && 341ebbfef2fSLiran Alon (!env->nested_state || 342ebbfef2fSLiran Alon !(env->nested_state->flags & KVM_STATE_NESTED_GUEST_MODE))) { 343ebbfef2fSLiran Alon error_report("vCPU set in guest-mode inconsistent with " 344ebbfef2fSLiran Alon "migrated kernel nested state"); 345ebbfef2fSLiran Alon return -EINVAL; 346ebbfef2fSLiran Alon } 347ebbfef2fSLiran Alon #endif 348ebbfef2fSLiran Alon 349fd13f23bSLiran Alon /* 350fd13f23bSLiran Alon * There are cases that we can get valid exception_nr with both 351fd13f23bSLiran Alon * exception_pending and exception_injected being cleared. 352fd13f23bSLiran Alon * This can happen in one of the following scenarios: 353fd13f23bSLiran Alon * 1) Source is older QEMU without KVM_CAP_EXCEPTION_PAYLOAD support. 354fd13f23bSLiran Alon * 2) Source is running on kernel without KVM_CAP_EXCEPTION_PAYLOAD support. 355fd13f23bSLiran Alon * 3) "cpu/exception_info" subsection not sent because there is no exception 356fd13f23bSLiran Alon * pending or guest wasn't running L2 (See comment in cpu_pre_save()). 357fd13f23bSLiran Alon * 358fd13f23bSLiran Alon * In those cases, we can just deduce that a valid exception_nr means 359fd13f23bSLiran Alon * we can treat the exception as already injected. 360fd13f23bSLiran Alon */ 361fd13f23bSLiran Alon if ((env->exception_nr != -1) && 362fd13f23bSLiran Alon !env->exception_pending && !env->exception_injected) { 363fd13f23bSLiran Alon env->exception_injected = 1; 364fd13f23bSLiran Alon } 365fd13f23bSLiran Alon 366468f6581SJuan Quintela env->fpstt = (env->fpus_vmstate >> 11) & 7; 367468f6581SJuan Quintela env->fpus = env->fpus_vmstate & ~0x3800; 368468f6581SJuan Quintela env->fptag_vmstate ^= 0xff; 369468f6581SJuan Quintela for(i = 0; i < 8; i++) { 370468f6581SJuan Quintela env->fptags[i] = (env->fptag_vmstate >> i) & 1; 371468f6581SJuan Quintela } 3721d8ad165SYang Zhong if (tcg_enabled()) { 37379c664f6SYang Zhong target_ulong dr7; 3745bde1407SPavel Dovgalyuk update_fp_status(env); 3751d8ad165SYang Zhong update_mxcsr_status(env); 376468f6581SJuan Quintela 377b3310ab3SAndreas Färber cpu_breakpoint_remove_all(cs, BP_CPU); 37875a34036SAndreas Färber cpu_watchpoint_remove_all(cs, BP_CPU); 37979c664f6SYang Zhong 38093d00d0fSRichard Henderson /* Indicate all breakpoints disabled, as they are, then 38193d00d0fSRichard Henderson let the helper re-enable them. */ 38279c664f6SYang Zhong dr7 = env->dr[7]; 38393d00d0fSRichard Henderson env->dr[7] = dr7 & ~(DR7_GLOBAL_BP_MASK | DR7_LOCAL_BP_MASK); 38493d00d0fSRichard Henderson cpu_x86_update_dr7(env, dr7); 385428065ceSliguang } 386d10eb08fSAlex Bennée tlb_flush(cs); 3871e7fbc6dSJuan Quintela return 0; 388468f6581SJuan Quintela } 389468f6581SJuan Quintela 390f6584ee2SGleb Natapov static bool async_pf_msr_needed(void *opaque) 391f6584ee2SGleb Natapov { 392f56e3a14SAndreas Färber X86CPU *cpu = opaque; 393f6584ee2SGleb Natapov 394f56e3a14SAndreas Färber return cpu->env.async_pf_en_msr != 0; 395f6584ee2SGleb Natapov } 396f6584ee2SGleb Natapov 397db5daafaSVitaly Kuznetsov static bool async_pf_int_msr_needed(void *opaque) 398db5daafaSVitaly Kuznetsov { 399db5daafaSVitaly Kuznetsov X86CPU *cpu = opaque; 400db5daafaSVitaly Kuznetsov 401db5daafaSVitaly Kuznetsov return cpu->env.async_pf_int_msr != 0; 402db5daafaSVitaly Kuznetsov } 403db5daafaSVitaly Kuznetsov 404bc9a839dSMichael S. Tsirkin static bool pv_eoi_msr_needed(void *opaque) 405bc9a839dSMichael S. Tsirkin { 406f56e3a14SAndreas Färber X86CPU *cpu = opaque; 407bc9a839dSMichael S. Tsirkin 408f56e3a14SAndreas Färber return cpu->env.pv_eoi_en_msr != 0; 409bc9a839dSMichael S. Tsirkin } 410bc9a839dSMichael S. Tsirkin 411917367aaSMarcelo Tosatti static bool steal_time_msr_needed(void *opaque) 412917367aaSMarcelo Tosatti { 4130e503577SMarcelo Tosatti X86CPU *cpu = opaque; 414917367aaSMarcelo Tosatti 4150e503577SMarcelo Tosatti return cpu->env.steal_time_msr != 0; 416917367aaSMarcelo Tosatti } 417917367aaSMarcelo Tosatti 418fd13f23bSLiran Alon static bool exception_info_needed(void *opaque) 419fd13f23bSLiran Alon { 420fd13f23bSLiran Alon X86CPU *cpu = opaque; 421fd13f23bSLiran Alon CPUX86State *env = &cpu->env; 422fd13f23bSLiran Alon 423fd13f23bSLiran Alon /* 424fd13f23bSLiran Alon * It is important to save exception-info only in case 4257332a4a4SCameron Esfahani * we need to distinguish between a pending and injected 426fd13f23bSLiran Alon * exception. Which is only required in case there is a 427fd13f23bSLiran Alon * pending exception and vCPU is running L2. 428fd13f23bSLiran Alon * For more info, refer to comment in cpu_pre_save(). 429fd13f23bSLiran Alon */ 430fd13f23bSLiran Alon return env->exception_pending && (env->hflags & HF_GUEST_MASK); 431fd13f23bSLiran Alon } 432fd13f23bSLiran Alon 433fd13f23bSLiran Alon static const VMStateDescription vmstate_exception_info = { 434fd13f23bSLiran Alon .name = "cpu/exception_info", 435fd13f23bSLiran Alon .version_id = 1, 436fd13f23bSLiran Alon .minimum_version_id = 1, 437fd13f23bSLiran Alon .needed = exception_info_needed, 438fd13f23bSLiran Alon .fields = (VMStateField[]) { 439fd13f23bSLiran Alon VMSTATE_UINT8(env.exception_pending, X86CPU), 440fd13f23bSLiran Alon VMSTATE_UINT8(env.exception_injected, X86CPU), 441fd13f23bSLiran Alon VMSTATE_UINT8(env.exception_has_payload, X86CPU), 442fd13f23bSLiran Alon VMSTATE_UINT64(env.exception_payload, X86CPU), 443fd13f23bSLiran Alon VMSTATE_END_OF_LIST() 444fd13f23bSLiran Alon } 445fd13f23bSLiran Alon }; 446fd13f23bSLiran Alon 447d645e132SMarcelo Tosatti /* Poll control MSR enabled by default */ 448d645e132SMarcelo Tosatti static bool poll_control_msr_needed(void *opaque) 449d645e132SMarcelo Tosatti { 450d645e132SMarcelo Tosatti X86CPU *cpu = opaque; 451d645e132SMarcelo Tosatti 452d645e132SMarcelo Tosatti return cpu->env.poll_control_msr != 1; 453d645e132SMarcelo Tosatti } 454d645e132SMarcelo Tosatti 455917367aaSMarcelo Tosatti static const VMStateDescription vmstate_steal_time_msr = { 456917367aaSMarcelo Tosatti .name = "cpu/steal_time_msr", 457917367aaSMarcelo Tosatti .version_id = 1, 458917367aaSMarcelo Tosatti .minimum_version_id = 1, 4595cd8cadaSJuan Quintela .needed = steal_time_msr_needed, 460917367aaSMarcelo Tosatti .fields = (VMStateField[]) { 4610e503577SMarcelo Tosatti VMSTATE_UINT64(env.steal_time_msr, X86CPU), 462917367aaSMarcelo Tosatti VMSTATE_END_OF_LIST() 463917367aaSMarcelo Tosatti } 464917367aaSMarcelo Tosatti }; 465917367aaSMarcelo Tosatti 466f6584ee2SGleb Natapov static const VMStateDescription vmstate_async_pf_msr = { 467f6584ee2SGleb Natapov .name = "cpu/async_pf_msr", 468f6584ee2SGleb Natapov .version_id = 1, 469f6584ee2SGleb Natapov .minimum_version_id = 1, 4705cd8cadaSJuan Quintela .needed = async_pf_msr_needed, 471f6584ee2SGleb Natapov .fields = (VMStateField[]) { 472f56e3a14SAndreas Färber VMSTATE_UINT64(env.async_pf_en_msr, X86CPU), 473f6584ee2SGleb Natapov VMSTATE_END_OF_LIST() 474f6584ee2SGleb Natapov } 475f6584ee2SGleb Natapov }; 476f6584ee2SGleb Natapov 477db5daafaSVitaly Kuznetsov static const VMStateDescription vmstate_async_pf_int_msr = { 478db5daafaSVitaly Kuznetsov .name = "cpu/async_pf_int_msr", 479db5daafaSVitaly Kuznetsov .version_id = 1, 480db5daafaSVitaly Kuznetsov .minimum_version_id = 1, 481db5daafaSVitaly Kuznetsov .needed = async_pf_int_msr_needed, 482db5daafaSVitaly Kuznetsov .fields = (VMStateField[]) { 483db5daafaSVitaly Kuznetsov VMSTATE_UINT64(env.async_pf_int_msr, X86CPU), 484db5daafaSVitaly Kuznetsov VMSTATE_END_OF_LIST() 485db5daafaSVitaly Kuznetsov } 486db5daafaSVitaly Kuznetsov }; 487db5daafaSVitaly Kuznetsov 488bc9a839dSMichael S. Tsirkin static const VMStateDescription vmstate_pv_eoi_msr = { 489bc9a839dSMichael S. Tsirkin .name = "cpu/async_pv_eoi_msr", 490bc9a839dSMichael S. Tsirkin .version_id = 1, 491bc9a839dSMichael S. Tsirkin .minimum_version_id = 1, 4925cd8cadaSJuan Quintela .needed = pv_eoi_msr_needed, 493bc9a839dSMichael S. Tsirkin .fields = (VMStateField[]) { 494f56e3a14SAndreas Färber VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU), 495bc9a839dSMichael S. Tsirkin VMSTATE_END_OF_LIST() 496bc9a839dSMichael S. Tsirkin } 497bc9a839dSMichael S. Tsirkin }; 498bc9a839dSMichael S. Tsirkin 499d645e132SMarcelo Tosatti static const VMStateDescription vmstate_poll_control_msr = { 500d645e132SMarcelo Tosatti .name = "cpu/poll_control_msr", 501d645e132SMarcelo Tosatti .version_id = 1, 502d645e132SMarcelo Tosatti .minimum_version_id = 1, 503d645e132SMarcelo Tosatti .needed = poll_control_msr_needed, 504d645e132SMarcelo Tosatti .fields = (VMStateField[]) { 505d645e132SMarcelo Tosatti VMSTATE_UINT64(env.poll_control_msr, X86CPU), 506d645e132SMarcelo Tosatti VMSTATE_END_OF_LIST() 507d645e132SMarcelo Tosatti } 508d645e132SMarcelo Tosatti }; 509d645e132SMarcelo Tosatti 51042cc8fa6SJan Kiszka static bool fpop_ip_dp_needed(void *opaque) 51142cc8fa6SJan Kiszka { 512f56e3a14SAndreas Färber X86CPU *cpu = opaque; 513f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 51442cc8fa6SJan Kiszka 51542cc8fa6SJan Kiszka return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0; 51642cc8fa6SJan Kiszka } 51742cc8fa6SJan Kiszka 51842cc8fa6SJan Kiszka static const VMStateDescription vmstate_fpop_ip_dp = { 51942cc8fa6SJan Kiszka .name = "cpu/fpop_ip_dp", 52042cc8fa6SJan Kiszka .version_id = 1, 52142cc8fa6SJan Kiszka .minimum_version_id = 1, 5225cd8cadaSJuan Quintela .needed = fpop_ip_dp_needed, 52342cc8fa6SJan Kiszka .fields = (VMStateField[]) { 524f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpop, X86CPU), 525f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpip, X86CPU), 526f56e3a14SAndreas Färber VMSTATE_UINT64(env.fpdp, X86CPU), 52742cc8fa6SJan Kiszka VMSTATE_END_OF_LIST() 52842cc8fa6SJan Kiszka } 52942cc8fa6SJan Kiszka }; 53042cc8fa6SJan Kiszka 531f28558d3SWill Auld static bool tsc_adjust_needed(void *opaque) 532f28558d3SWill Auld { 533f56e3a14SAndreas Färber X86CPU *cpu = opaque; 534f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 535f28558d3SWill Auld 536f28558d3SWill Auld return env->tsc_adjust != 0; 537f28558d3SWill Auld } 538f28558d3SWill Auld 539f28558d3SWill Auld static const VMStateDescription vmstate_msr_tsc_adjust = { 540f28558d3SWill Auld .name = "cpu/msr_tsc_adjust", 541f28558d3SWill Auld .version_id = 1, 542f28558d3SWill Auld .minimum_version_id = 1, 5435cd8cadaSJuan Quintela .needed = tsc_adjust_needed, 544f28558d3SWill Auld .fields = (VMStateField[]) { 545f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_adjust, X86CPU), 546f28558d3SWill Auld VMSTATE_END_OF_LIST() 547f28558d3SWill Auld } 548f28558d3SWill Auld }; 549f28558d3SWill Auld 550e13713dbSLiran Alon static bool msr_smi_count_needed(void *opaque) 551e13713dbSLiran Alon { 552e13713dbSLiran Alon X86CPU *cpu = opaque; 553e13713dbSLiran Alon CPUX86State *env = &cpu->env; 554e13713dbSLiran Alon 555990e0be2SPaolo Bonzini return cpu->migrate_smi_count && env->msr_smi_count != 0; 556e13713dbSLiran Alon } 557e13713dbSLiran Alon 558e13713dbSLiran Alon static const VMStateDescription vmstate_msr_smi_count = { 559e13713dbSLiran Alon .name = "cpu/msr_smi_count", 560e13713dbSLiran Alon .version_id = 1, 561e13713dbSLiran Alon .minimum_version_id = 1, 562e13713dbSLiran Alon .needed = msr_smi_count_needed, 563e13713dbSLiran Alon .fields = (VMStateField[]) { 564e13713dbSLiran Alon VMSTATE_UINT64(env.msr_smi_count, X86CPU), 565e13713dbSLiran Alon VMSTATE_END_OF_LIST() 566e13713dbSLiran Alon } 567e13713dbSLiran Alon }; 568e13713dbSLiran Alon 569aa82ba54SLiu, Jinsong static bool tscdeadline_needed(void *opaque) 570aa82ba54SLiu, Jinsong { 571f56e3a14SAndreas Färber X86CPU *cpu = opaque; 572f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 573aa82ba54SLiu, Jinsong 574aa82ba54SLiu, Jinsong return env->tsc_deadline != 0; 575aa82ba54SLiu, Jinsong } 576aa82ba54SLiu, Jinsong 577aa82ba54SLiu, Jinsong static const VMStateDescription vmstate_msr_tscdeadline = { 578aa82ba54SLiu, Jinsong .name = "cpu/msr_tscdeadline", 579aa82ba54SLiu, Jinsong .version_id = 1, 580aa82ba54SLiu, Jinsong .minimum_version_id = 1, 5815cd8cadaSJuan Quintela .needed = tscdeadline_needed, 582aa82ba54SLiu, Jinsong .fields = (VMStateField[]) { 583f56e3a14SAndreas Färber VMSTATE_UINT64(env.tsc_deadline, X86CPU), 584aa82ba54SLiu, Jinsong VMSTATE_END_OF_LIST() 585aa82ba54SLiu, Jinsong } 586aa82ba54SLiu, Jinsong }; 587aa82ba54SLiu, Jinsong 58821e87c46SAvi Kivity static bool misc_enable_needed(void *opaque) 58921e87c46SAvi Kivity { 590f56e3a14SAndreas Färber X86CPU *cpu = opaque; 591f56e3a14SAndreas Färber CPUX86State *env = &cpu->env; 59221e87c46SAvi Kivity 59321e87c46SAvi Kivity return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT; 59421e87c46SAvi Kivity } 59521e87c46SAvi Kivity 5960779caebSArthur Chunqi Li static bool feature_control_needed(void *opaque) 5970779caebSArthur Chunqi Li { 5980779caebSArthur Chunqi Li X86CPU *cpu = opaque; 5990779caebSArthur Chunqi Li CPUX86State *env = &cpu->env; 6000779caebSArthur Chunqi Li 6010779caebSArthur Chunqi Li return env->msr_ia32_feature_control != 0; 6020779caebSArthur Chunqi Li } 6030779caebSArthur Chunqi Li 60421e87c46SAvi Kivity static const VMStateDescription vmstate_msr_ia32_misc_enable = { 60521e87c46SAvi Kivity .name = "cpu/msr_ia32_misc_enable", 60621e87c46SAvi Kivity .version_id = 1, 60721e87c46SAvi Kivity .minimum_version_id = 1, 6085cd8cadaSJuan Quintela .needed = misc_enable_needed, 60921e87c46SAvi Kivity .fields = (VMStateField[]) { 610f56e3a14SAndreas Färber VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU), 61121e87c46SAvi Kivity VMSTATE_END_OF_LIST() 61221e87c46SAvi Kivity } 61321e87c46SAvi Kivity }; 61421e87c46SAvi Kivity 6150779caebSArthur Chunqi Li static const VMStateDescription vmstate_msr_ia32_feature_control = { 6160779caebSArthur Chunqi Li .name = "cpu/msr_ia32_feature_control", 6170779caebSArthur Chunqi Li .version_id = 1, 6180779caebSArthur Chunqi Li .minimum_version_id = 1, 6195cd8cadaSJuan Quintela .needed = feature_control_needed, 6200779caebSArthur Chunqi Li .fields = (VMStateField[]) { 6210779caebSArthur Chunqi Li VMSTATE_UINT64(env.msr_ia32_feature_control, X86CPU), 6220779caebSArthur Chunqi Li VMSTATE_END_OF_LIST() 6230779caebSArthur Chunqi Li } 6240779caebSArthur Chunqi Li }; 6250779caebSArthur Chunqi Li 6260d894367SPaolo Bonzini static bool pmu_enable_needed(void *opaque) 6270d894367SPaolo Bonzini { 6280d894367SPaolo Bonzini X86CPU *cpu = opaque; 6290d894367SPaolo Bonzini CPUX86State *env = &cpu->env; 6300d894367SPaolo Bonzini int i; 6310d894367SPaolo Bonzini 6320d894367SPaolo Bonzini if (env->msr_fixed_ctr_ctrl || env->msr_global_ctrl || 6330d894367SPaolo Bonzini env->msr_global_status || env->msr_global_ovf_ctrl) { 6340d894367SPaolo Bonzini return true; 6350d894367SPaolo Bonzini } 6360d894367SPaolo Bonzini for (i = 0; i < MAX_FIXED_COUNTERS; i++) { 6370d894367SPaolo Bonzini if (env->msr_fixed_counters[i]) { 6380d894367SPaolo Bonzini return true; 6390d894367SPaolo Bonzini } 6400d894367SPaolo Bonzini } 6410d894367SPaolo Bonzini for (i = 0; i < MAX_GP_COUNTERS; i++) { 6420d894367SPaolo Bonzini if (env->msr_gp_counters[i] || env->msr_gp_evtsel[i]) { 6430d894367SPaolo Bonzini return true; 6440d894367SPaolo Bonzini } 6450d894367SPaolo Bonzini } 6460d894367SPaolo Bonzini 6470d894367SPaolo Bonzini return false; 6480d894367SPaolo Bonzini } 6490d894367SPaolo Bonzini 6500d894367SPaolo Bonzini static const VMStateDescription vmstate_msr_architectural_pmu = { 6510d894367SPaolo Bonzini .name = "cpu/msr_architectural_pmu", 6520d894367SPaolo Bonzini .version_id = 1, 6530d894367SPaolo Bonzini .minimum_version_id = 1, 6545cd8cadaSJuan Quintela .needed = pmu_enable_needed, 6550d894367SPaolo Bonzini .fields = (VMStateField[]) { 6560d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_fixed_ctr_ctrl, X86CPU), 6570d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ctrl, X86CPU), 6580d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_status, X86CPU), 6590d894367SPaolo Bonzini VMSTATE_UINT64(env.msr_global_ovf_ctrl, X86CPU), 6600d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_fixed_counters, X86CPU, MAX_FIXED_COUNTERS), 6610d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_counters, X86CPU, MAX_GP_COUNTERS), 6620d894367SPaolo Bonzini VMSTATE_UINT64_ARRAY(env.msr_gp_evtsel, X86CPU, MAX_GP_COUNTERS), 6630d894367SPaolo Bonzini VMSTATE_END_OF_LIST() 6640d894367SPaolo Bonzini } 6650d894367SPaolo Bonzini }; 6660d894367SPaolo Bonzini 66779e9ebebSLiu Jinsong static bool mpx_needed(void *opaque) 66879e9ebebSLiu Jinsong { 66979e9ebebSLiu Jinsong X86CPU *cpu = opaque; 67079e9ebebSLiu Jinsong CPUX86State *env = &cpu->env; 67179e9ebebSLiu Jinsong unsigned int i; 67279e9ebebSLiu Jinsong 67379e9ebebSLiu Jinsong for (i = 0; i < 4; i++) { 67479e9ebebSLiu Jinsong if (env->bnd_regs[i].lb || env->bnd_regs[i].ub) { 67579e9ebebSLiu Jinsong return true; 67679e9ebebSLiu Jinsong } 67779e9ebebSLiu Jinsong } 67879e9ebebSLiu Jinsong 67979e9ebebSLiu Jinsong if (env->bndcs_regs.cfgu || env->bndcs_regs.sts) { 68079e9ebebSLiu Jinsong return true; 68179e9ebebSLiu Jinsong } 68279e9ebebSLiu Jinsong 68379e9ebebSLiu Jinsong return !!env->msr_bndcfgs; 68479e9ebebSLiu Jinsong } 68579e9ebebSLiu Jinsong 68679e9ebebSLiu Jinsong static const VMStateDescription vmstate_mpx = { 68779e9ebebSLiu Jinsong .name = "cpu/mpx", 68879e9ebebSLiu Jinsong .version_id = 1, 68979e9ebebSLiu Jinsong .minimum_version_id = 1, 6905cd8cadaSJuan Quintela .needed = mpx_needed, 69179e9ebebSLiu Jinsong .fields = (VMStateField[]) { 69279e9ebebSLiu Jinsong VMSTATE_BND_REGS(env.bnd_regs, X86CPU, 4), 69379e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.cfgu, X86CPU), 69479e9ebebSLiu Jinsong VMSTATE_UINT64(env.bndcs_regs.sts, X86CPU), 69579e9ebebSLiu Jinsong VMSTATE_UINT64(env.msr_bndcfgs, X86CPU), 69679e9ebebSLiu Jinsong VMSTATE_END_OF_LIST() 69779e9ebebSLiu Jinsong } 69879e9ebebSLiu Jinsong }; 69979e9ebebSLiu Jinsong 7001c90ef26SVadim Rozenfeld static bool hyperv_hypercall_enable_needed(void *opaque) 7011c90ef26SVadim Rozenfeld { 7021c90ef26SVadim Rozenfeld X86CPU *cpu = opaque; 7031c90ef26SVadim Rozenfeld CPUX86State *env = &cpu->env; 7041c90ef26SVadim Rozenfeld 7051c90ef26SVadim Rozenfeld return env->msr_hv_hypercall != 0 || env->msr_hv_guest_os_id != 0; 7061c90ef26SVadim Rozenfeld } 7071c90ef26SVadim Rozenfeld 7081c90ef26SVadim Rozenfeld static const VMStateDescription vmstate_msr_hypercall_hypercall = { 7091c90ef26SVadim Rozenfeld .name = "cpu/msr_hyperv_hypercall", 7101c90ef26SVadim Rozenfeld .version_id = 1, 7111c90ef26SVadim Rozenfeld .minimum_version_id = 1, 7125cd8cadaSJuan Quintela .needed = hyperv_hypercall_enable_needed, 7131c90ef26SVadim Rozenfeld .fields = (VMStateField[]) { 7141c90ef26SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_guest_os_id, X86CPU), 715466e6e9dSPaolo Bonzini VMSTATE_UINT64(env.msr_hv_hypercall, X86CPU), 7161c90ef26SVadim Rozenfeld VMSTATE_END_OF_LIST() 7171c90ef26SVadim Rozenfeld } 7181c90ef26SVadim Rozenfeld }; 7191c90ef26SVadim Rozenfeld 7205ef68987SVadim Rozenfeld static bool hyperv_vapic_enable_needed(void *opaque) 7215ef68987SVadim Rozenfeld { 7225ef68987SVadim Rozenfeld X86CPU *cpu = opaque; 7235ef68987SVadim Rozenfeld CPUX86State *env = &cpu->env; 7245ef68987SVadim Rozenfeld 7255ef68987SVadim Rozenfeld return env->msr_hv_vapic != 0; 7265ef68987SVadim Rozenfeld } 7275ef68987SVadim Rozenfeld 7285ef68987SVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_vapic = { 7295ef68987SVadim Rozenfeld .name = "cpu/msr_hyperv_vapic", 7305ef68987SVadim Rozenfeld .version_id = 1, 7315ef68987SVadim Rozenfeld .minimum_version_id = 1, 7325cd8cadaSJuan Quintela .needed = hyperv_vapic_enable_needed, 7335ef68987SVadim Rozenfeld .fields = (VMStateField[]) { 7345ef68987SVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_vapic, X86CPU), 7355ef68987SVadim Rozenfeld VMSTATE_END_OF_LIST() 7365ef68987SVadim Rozenfeld } 7375ef68987SVadim Rozenfeld }; 7385ef68987SVadim Rozenfeld 73948a5f3bcSVadim Rozenfeld static bool hyperv_time_enable_needed(void *opaque) 74048a5f3bcSVadim Rozenfeld { 74148a5f3bcSVadim Rozenfeld X86CPU *cpu = opaque; 74248a5f3bcSVadim Rozenfeld CPUX86State *env = &cpu->env; 74348a5f3bcSVadim Rozenfeld 74448a5f3bcSVadim Rozenfeld return env->msr_hv_tsc != 0; 74548a5f3bcSVadim Rozenfeld } 74648a5f3bcSVadim Rozenfeld 74748a5f3bcSVadim Rozenfeld static const VMStateDescription vmstate_msr_hyperv_time = { 74848a5f3bcSVadim Rozenfeld .name = "cpu/msr_hyperv_time", 74948a5f3bcSVadim Rozenfeld .version_id = 1, 75048a5f3bcSVadim Rozenfeld .minimum_version_id = 1, 7515cd8cadaSJuan Quintela .needed = hyperv_time_enable_needed, 75248a5f3bcSVadim Rozenfeld .fields = (VMStateField[]) { 75348a5f3bcSVadim Rozenfeld VMSTATE_UINT64(env.msr_hv_tsc, X86CPU), 75448a5f3bcSVadim Rozenfeld VMSTATE_END_OF_LIST() 75548a5f3bcSVadim Rozenfeld } 75648a5f3bcSVadim Rozenfeld }; 75748a5f3bcSVadim Rozenfeld 758f2a53c9eSAndrey Smetanin static bool hyperv_crash_enable_needed(void *opaque) 759f2a53c9eSAndrey Smetanin { 760f2a53c9eSAndrey Smetanin X86CPU *cpu = opaque; 761f2a53c9eSAndrey Smetanin CPUX86State *env = &cpu->env; 762f2a53c9eSAndrey Smetanin int i; 763f2a53c9eSAndrey Smetanin 7645e953812SRoman Kagan for (i = 0; i < HV_CRASH_PARAMS; i++) { 765f2a53c9eSAndrey Smetanin if (env->msr_hv_crash_params[i]) { 766f2a53c9eSAndrey Smetanin return true; 767f2a53c9eSAndrey Smetanin } 768f2a53c9eSAndrey Smetanin } 769f2a53c9eSAndrey Smetanin return false; 770f2a53c9eSAndrey Smetanin } 771f2a53c9eSAndrey Smetanin 772f2a53c9eSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_crash = { 773f2a53c9eSAndrey Smetanin .name = "cpu/msr_hyperv_crash", 774f2a53c9eSAndrey Smetanin .version_id = 1, 775f2a53c9eSAndrey Smetanin .minimum_version_id = 1, 776f2a53c9eSAndrey Smetanin .needed = hyperv_crash_enable_needed, 777f2a53c9eSAndrey Smetanin .fields = (VMStateField[]) { 7785e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_crash_params, X86CPU, HV_CRASH_PARAMS), 779f2a53c9eSAndrey Smetanin VMSTATE_END_OF_LIST() 780f2a53c9eSAndrey Smetanin } 781f2a53c9eSAndrey Smetanin }; 782f2a53c9eSAndrey Smetanin 78346eb8f98SAndrey Smetanin static bool hyperv_runtime_enable_needed(void *opaque) 78446eb8f98SAndrey Smetanin { 78546eb8f98SAndrey Smetanin X86CPU *cpu = opaque; 78646eb8f98SAndrey Smetanin CPUX86State *env = &cpu->env; 78746eb8f98SAndrey Smetanin 7882d384d7cSVitaly Kuznetsov if (!hyperv_feat_enabled(cpu, HYPERV_FEAT_RUNTIME)) { 78951227875SZhuangYanying return false; 79051227875SZhuangYanying } 79151227875SZhuangYanying 79246eb8f98SAndrey Smetanin return env->msr_hv_runtime != 0; 79346eb8f98SAndrey Smetanin } 79446eb8f98SAndrey Smetanin 79546eb8f98SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_runtime = { 79646eb8f98SAndrey Smetanin .name = "cpu/msr_hyperv_runtime", 79746eb8f98SAndrey Smetanin .version_id = 1, 79846eb8f98SAndrey Smetanin .minimum_version_id = 1, 79946eb8f98SAndrey Smetanin .needed = hyperv_runtime_enable_needed, 80046eb8f98SAndrey Smetanin .fields = (VMStateField[]) { 80146eb8f98SAndrey Smetanin VMSTATE_UINT64(env.msr_hv_runtime, X86CPU), 80246eb8f98SAndrey Smetanin VMSTATE_END_OF_LIST() 80346eb8f98SAndrey Smetanin } 80446eb8f98SAndrey Smetanin }; 80546eb8f98SAndrey Smetanin 806866eea9aSAndrey Smetanin static bool hyperv_synic_enable_needed(void *opaque) 807866eea9aSAndrey Smetanin { 808866eea9aSAndrey Smetanin X86CPU *cpu = opaque; 809866eea9aSAndrey Smetanin CPUX86State *env = &cpu->env; 810866eea9aSAndrey Smetanin int i; 811866eea9aSAndrey Smetanin 812866eea9aSAndrey Smetanin if (env->msr_hv_synic_control != 0 || 813866eea9aSAndrey Smetanin env->msr_hv_synic_evt_page != 0 || 814866eea9aSAndrey Smetanin env->msr_hv_synic_msg_page != 0) { 815866eea9aSAndrey Smetanin return true; 816866eea9aSAndrey Smetanin } 817866eea9aSAndrey Smetanin 818866eea9aSAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_synic_sint); i++) { 819866eea9aSAndrey Smetanin if (env->msr_hv_synic_sint[i] != 0) { 820866eea9aSAndrey Smetanin return true; 821866eea9aSAndrey Smetanin } 822866eea9aSAndrey Smetanin } 823866eea9aSAndrey Smetanin 824866eea9aSAndrey Smetanin return false; 825866eea9aSAndrey Smetanin } 826866eea9aSAndrey Smetanin 827606c34bfSRoman Kagan static int hyperv_synic_post_load(void *opaque, int version_id) 828606c34bfSRoman Kagan { 829606c34bfSRoman Kagan X86CPU *cpu = opaque; 830606c34bfSRoman Kagan hyperv_x86_synic_update(cpu); 831606c34bfSRoman Kagan return 0; 832606c34bfSRoman Kagan } 833606c34bfSRoman Kagan 834866eea9aSAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_synic = { 835866eea9aSAndrey Smetanin .name = "cpu/msr_hyperv_synic", 836866eea9aSAndrey Smetanin .version_id = 1, 837866eea9aSAndrey Smetanin .minimum_version_id = 1, 838866eea9aSAndrey Smetanin .needed = hyperv_synic_enable_needed, 839606c34bfSRoman Kagan .post_load = hyperv_synic_post_load, 840866eea9aSAndrey Smetanin .fields = (VMStateField[]) { 841866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_control, X86CPU), 842866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_evt_page, X86CPU), 843866eea9aSAndrey Smetanin VMSTATE_UINT64(env.msr_hv_synic_msg_page, X86CPU), 8445e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_synic_sint, X86CPU, HV_SINT_COUNT), 845866eea9aSAndrey Smetanin VMSTATE_END_OF_LIST() 846866eea9aSAndrey Smetanin } 847866eea9aSAndrey Smetanin }; 848866eea9aSAndrey Smetanin 849ff99aa64SAndrey Smetanin static bool hyperv_stimer_enable_needed(void *opaque) 850ff99aa64SAndrey Smetanin { 851ff99aa64SAndrey Smetanin X86CPU *cpu = opaque; 852ff99aa64SAndrey Smetanin CPUX86State *env = &cpu->env; 853ff99aa64SAndrey Smetanin int i; 854ff99aa64SAndrey Smetanin 855ff99aa64SAndrey Smetanin for (i = 0; i < ARRAY_SIZE(env->msr_hv_stimer_config); i++) { 856ff99aa64SAndrey Smetanin if (env->msr_hv_stimer_config[i] || env->msr_hv_stimer_count[i]) { 857ff99aa64SAndrey Smetanin return true; 858ff99aa64SAndrey Smetanin } 859ff99aa64SAndrey Smetanin } 860ff99aa64SAndrey Smetanin return false; 861ff99aa64SAndrey Smetanin } 862ff99aa64SAndrey Smetanin 863ff99aa64SAndrey Smetanin static const VMStateDescription vmstate_msr_hyperv_stimer = { 864ff99aa64SAndrey Smetanin .name = "cpu/msr_hyperv_stimer", 865ff99aa64SAndrey Smetanin .version_id = 1, 866ff99aa64SAndrey Smetanin .minimum_version_id = 1, 867ff99aa64SAndrey Smetanin .needed = hyperv_stimer_enable_needed, 868ff99aa64SAndrey Smetanin .fields = (VMStateField[]) { 8695e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_config, X86CPU, 8705e953812SRoman Kagan HV_STIMER_COUNT), 8715e953812SRoman Kagan VMSTATE_UINT64_ARRAY(env.msr_hv_stimer_count, X86CPU, HV_STIMER_COUNT), 872ff99aa64SAndrey Smetanin VMSTATE_END_OF_LIST() 873ff99aa64SAndrey Smetanin } 874ff99aa64SAndrey Smetanin }; 875ff99aa64SAndrey Smetanin 876ba6a4fd9SVitaly Kuznetsov static bool hyperv_reenlightenment_enable_needed(void *opaque) 877ba6a4fd9SVitaly Kuznetsov { 878ba6a4fd9SVitaly Kuznetsov X86CPU *cpu = opaque; 879ba6a4fd9SVitaly Kuznetsov CPUX86State *env = &cpu->env; 880ba6a4fd9SVitaly Kuznetsov 881ba6a4fd9SVitaly Kuznetsov return env->msr_hv_reenlightenment_control != 0 || 882ba6a4fd9SVitaly Kuznetsov env->msr_hv_tsc_emulation_control != 0 || 883ba6a4fd9SVitaly Kuznetsov env->msr_hv_tsc_emulation_status != 0; 884ba6a4fd9SVitaly Kuznetsov } 885ba6a4fd9SVitaly Kuznetsov 886ba6a4fd9SVitaly Kuznetsov static const VMStateDescription vmstate_msr_hyperv_reenlightenment = { 887ba6a4fd9SVitaly Kuznetsov .name = "cpu/msr_hyperv_reenlightenment", 888ba6a4fd9SVitaly Kuznetsov .version_id = 1, 889ba6a4fd9SVitaly Kuznetsov .minimum_version_id = 1, 890ba6a4fd9SVitaly Kuznetsov .needed = hyperv_reenlightenment_enable_needed, 891ba6a4fd9SVitaly Kuznetsov .fields = (VMStateField[]) { 892ba6a4fd9SVitaly Kuznetsov VMSTATE_UINT64(env.msr_hv_reenlightenment_control, X86CPU), 893ba6a4fd9SVitaly Kuznetsov VMSTATE_UINT64(env.msr_hv_tsc_emulation_control, X86CPU), 894ba6a4fd9SVitaly Kuznetsov VMSTATE_UINT64(env.msr_hv_tsc_emulation_status, X86CPU), 895ba6a4fd9SVitaly Kuznetsov VMSTATE_END_OF_LIST() 896ba6a4fd9SVitaly Kuznetsov } 897ba6a4fd9SVitaly Kuznetsov }; 898ba6a4fd9SVitaly Kuznetsov 8999aecd6f8SChao Peng static bool avx512_needed(void *opaque) 9009aecd6f8SChao Peng { 9019aecd6f8SChao Peng X86CPU *cpu = opaque; 9029aecd6f8SChao Peng CPUX86State *env = &cpu->env; 9039aecd6f8SChao Peng unsigned int i; 9049aecd6f8SChao Peng 9059aecd6f8SChao Peng for (i = 0; i < NB_OPMASK_REGS; i++) { 9069aecd6f8SChao Peng if (env->opmask_regs[i]) { 9079aecd6f8SChao Peng return true; 9089aecd6f8SChao Peng } 9099aecd6f8SChao Peng } 9109aecd6f8SChao Peng 9119aecd6f8SChao Peng for (i = 0; i < CPU_NB_REGS; i++) { 91219cbd87cSEduardo Habkost #define ENV_XMM(reg, field) (env->xmm_regs[reg].ZMM_Q(field)) 913b7711471SPaolo Bonzini if (ENV_XMM(i, 4) || ENV_XMM(i, 6) || 914b7711471SPaolo Bonzini ENV_XMM(i, 5) || ENV_XMM(i, 7)) { 9159aecd6f8SChao Peng return true; 9169aecd6f8SChao Peng } 9179aecd6f8SChao Peng #ifdef TARGET_X86_64 918b7711471SPaolo Bonzini if (ENV_XMM(i+16, 0) || ENV_XMM(i+16, 1) || 919b7711471SPaolo Bonzini ENV_XMM(i+16, 2) || ENV_XMM(i+16, 3) || 920b7711471SPaolo Bonzini ENV_XMM(i+16, 4) || ENV_XMM(i+16, 5) || 921b7711471SPaolo Bonzini ENV_XMM(i+16, 6) || ENV_XMM(i+16, 7)) { 9229aecd6f8SChao Peng return true; 9239aecd6f8SChao Peng } 9249aecd6f8SChao Peng #endif 9259aecd6f8SChao Peng } 9269aecd6f8SChao Peng 9279aecd6f8SChao Peng return false; 9289aecd6f8SChao Peng } 9299aecd6f8SChao Peng 9309aecd6f8SChao Peng static const VMStateDescription vmstate_avx512 = { 9319aecd6f8SChao Peng .name = "cpu/avx512", 9329aecd6f8SChao Peng .version_id = 1, 9339aecd6f8SChao Peng .minimum_version_id = 1, 9345cd8cadaSJuan Quintela .needed = avx512_needed, 9359aecd6f8SChao Peng .fields = (VMStateField[]) { 9369aecd6f8SChao Peng VMSTATE_UINT64_ARRAY(env.opmask_regs, X86CPU, NB_OPMASK_REGS), 937b7711471SPaolo Bonzini VMSTATE_ZMMH_REGS_VARS(env.xmm_regs, X86CPU, 0), 9389aecd6f8SChao Peng #ifdef TARGET_X86_64 939b7711471SPaolo Bonzini VMSTATE_Hi16_ZMM_REGS_VARS(env.xmm_regs, X86CPU, 16), 9409aecd6f8SChao Peng #endif 9419aecd6f8SChao Peng VMSTATE_END_OF_LIST() 9429aecd6f8SChao Peng } 9439aecd6f8SChao Peng }; 9449aecd6f8SChao Peng 94518cd2c17SWanpeng Li static bool xss_needed(void *opaque) 94618cd2c17SWanpeng Li { 94718cd2c17SWanpeng Li X86CPU *cpu = opaque; 94818cd2c17SWanpeng Li CPUX86State *env = &cpu->env; 94918cd2c17SWanpeng Li 95018cd2c17SWanpeng Li return env->xss != 0; 95118cd2c17SWanpeng Li } 95218cd2c17SWanpeng Li 95318cd2c17SWanpeng Li static const VMStateDescription vmstate_xss = { 95418cd2c17SWanpeng Li .name = "cpu/xss", 95518cd2c17SWanpeng Li .version_id = 1, 95618cd2c17SWanpeng Li .minimum_version_id = 1, 9575cd8cadaSJuan Quintela .needed = xss_needed, 95818cd2c17SWanpeng Li .fields = (VMStateField[]) { 95918cd2c17SWanpeng Li VMSTATE_UINT64(env.xss, X86CPU), 96018cd2c17SWanpeng Li VMSTATE_END_OF_LIST() 96118cd2c17SWanpeng Li } 96218cd2c17SWanpeng Li }; 96318cd2c17SWanpeng Li 96465087997STao Xu static bool umwait_needed(void *opaque) 96565087997STao Xu { 96665087997STao Xu X86CPU *cpu = opaque; 96765087997STao Xu CPUX86State *env = &cpu->env; 96865087997STao Xu 96965087997STao Xu return env->umwait != 0; 97065087997STao Xu } 97165087997STao Xu 97265087997STao Xu static const VMStateDescription vmstate_umwait = { 97365087997STao Xu .name = "cpu/umwait", 97465087997STao Xu .version_id = 1, 97565087997STao Xu .minimum_version_id = 1, 97665087997STao Xu .needed = umwait_needed, 97765087997STao Xu .fields = (VMStateField[]) { 97865087997STao Xu VMSTATE_UINT32(env.umwait, X86CPU), 97965087997STao Xu VMSTATE_END_OF_LIST() 98065087997STao Xu } 98165087997STao Xu }; 98265087997STao Xu 983f74eefe0SHuaitong Han #ifdef TARGET_X86_64 984f74eefe0SHuaitong Han static bool pkru_needed(void *opaque) 985f74eefe0SHuaitong Han { 986f74eefe0SHuaitong Han X86CPU *cpu = opaque; 987f74eefe0SHuaitong Han CPUX86State *env = &cpu->env; 988f74eefe0SHuaitong Han 989f74eefe0SHuaitong Han return env->pkru != 0; 990f74eefe0SHuaitong Han } 991f74eefe0SHuaitong Han 992f74eefe0SHuaitong Han static const VMStateDescription vmstate_pkru = { 993f74eefe0SHuaitong Han .name = "cpu/pkru", 994f74eefe0SHuaitong Han .version_id = 1, 995f74eefe0SHuaitong Han .minimum_version_id = 1, 996f74eefe0SHuaitong Han .needed = pkru_needed, 997f74eefe0SHuaitong Han .fields = (VMStateField[]){ 998f74eefe0SHuaitong Han VMSTATE_UINT32(env.pkru, X86CPU), 999f74eefe0SHuaitong Han VMSTATE_END_OF_LIST() 1000f74eefe0SHuaitong Han } 1001f74eefe0SHuaitong Han }; 1002f74eefe0SHuaitong Han #endif 1003f74eefe0SHuaitong Han 100436f96c4bSHaozhong Zhang static bool tsc_khz_needed(void *opaque) 100536f96c4bSHaozhong Zhang { 100636f96c4bSHaozhong Zhang X86CPU *cpu = opaque; 100736f96c4bSHaozhong Zhang CPUX86State *env = &cpu->env; 100836f96c4bSHaozhong Zhang MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); 10092f34ebf2SLiam Merwick X86MachineClass *x86mc = X86_MACHINE_CLASS(mc); 10102f34ebf2SLiam Merwick return env->tsc_khz && x86mc->save_tsc_khz; 101136f96c4bSHaozhong Zhang } 101236f96c4bSHaozhong Zhang 101336f96c4bSHaozhong Zhang static const VMStateDescription vmstate_tsc_khz = { 101436f96c4bSHaozhong Zhang .name = "cpu/tsc_khz", 101536f96c4bSHaozhong Zhang .version_id = 1, 101636f96c4bSHaozhong Zhang .minimum_version_id = 1, 101736f96c4bSHaozhong Zhang .needed = tsc_khz_needed, 101836f96c4bSHaozhong Zhang .fields = (VMStateField[]) { 101936f96c4bSHaozhong Zhang VMSTATE_INT64(env.tsc_khz, X86CPU), 102036f96c4bSHaozhong Zhang VMSTATE_END_OF_LIST() 102136f96c4bSHaozhong Zhang } 102236f96c4bSHaozhong Zhang }; 102336f96c4bSHaozhong Zhang 1024ebbfef2fSLiran Alon #ifdef CONFIG_KVM 1025ebbfef2fSLiran Alon 1026ebbfef2fSLiran Alon static bool vmx_vmcs12_needed(void *opaque) 1027ebbfef2fSLiran Alon { 1028ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = opaque; 1029ebbfef2fSLiran Alon return (nested_state->size > 1030ebbfef2fSLiran Alon offsetof(struct kvm_nested_state, data.vmx[0].vmcs12)); 1031ebbfef2fSLiran Alon } 1032ebbfef2fSLiran Alon 1033ebbfef2fSLiran Alon static const VMStateDescription vmstate_vmx_vmcs12 = { 1034ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state/vmx/vmcs12", 1035ebbfef2fSLiran Alon .version_id = 1, 1036ebbfef2fSLiran Alon .minimum_version_id = 1, 1037ebbfef2fSLiran Alon .needed = vmx_vmcs12_needed, 1038ebbfef2fSLiran Alon .fields = (VMStateField[]) { 1039ebbfef2fSLiran Alon VMSTATE_UINT8_ARRAY(data.vmx[0].vmcs12, 1040ebbfef2fSLiran Alon struct kvm_nested_state, 1041ebbfef2fSLiran Alon KVM_STATE_NESTED_VMX_VMCS_SIZE), 1042ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1043ebbfef2fSLiran Alon } 1044ebbfef2fSLiran Alon }; 1045ebbfef2fSLiran Alon 1046ebbfef2fSLiran Alon static bool vmx_shadow_vmcs12_needed(void *opaque) 1047ebbfef2fSLiran Alon { 1048ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = opaque; 1049ebbfef2fSLiran Alon return (nested_state->size > 1050ebbfef2fSLiran Alon offsetof(struct kvm_nested_state, data.vmx[0].shadow_vmcs12)); 1051ebbfef2fSLiran Alon } 1052ebbfef2fSLiran Alon 1053ebbfef2fSLiran Alon static const VMStateDescription vmstate_vmx_shadow_vmcs12 = { 1054ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state/vmx/shadow_vmcs12", 1055ebbfef2fSLiran Alon .version_id = 1, 1056ebbfef2fSLiran Alon .minimum_version_id = 1, 1057ebbfef2fSLiran Alon .needed = vmx_shadow_vmcs12_needed, 1058ebbfef2fSLiran Alon .fields = (VMStateField[]) { 1059ebbfef2fSLiran Alon VMSTATE_UINT8_ARRAY(data.vmx[0].shadow_vmcs12, 1060ebbfef2fSLiran Alon struct kvm_nested_state, 1061ebbfef2fSLiran Alon KVM_STATE_NESTED_VMX_VMCS_SIZE), 1062ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1063ebbfef2fSLiran Alon } 1064ebbfef2fSLiran Alon }; 1065ebbfef2fSLiran Alon 1066ebbfef2fSLiran Alon static bool vmx_nested_state_needed(void *opaque) 1067ebbfef2fSLiran Alon { 1068ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = opaque; 1069ebbfef2fSLiran Alon 1070ec7b1bbdSLiran Alon return (nested_state->format == KVM_STATE_NESTED_FORMAT_VMX && 1071ec7b1bbdSLiran Alon nested_state->hdr.vmx.vmxon_pa != -1ull); 1072ebbfef2fSLiran Alon } 1073ebbfef2fSLiran Alon 1074ebbfef2fSLiran Alon static const VMStateDescription vmstate_vmx_nested_state = { 1075ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state/vmx", 1076ebbfef2fSLiran Alon .version_id = 1, 1077ebbfef2fSLiran Alon .minimum_version_id = 1, 1078ebbfef2fSLiran Alon .needed = vmx_nested_state_needed, 1079ebbfef2fSLiran Alon .fields = (VMStateField[]) { 1080ebbfef2fSLiran Alon VMSTATE_U64(hdr.vmx.vmxon_pa, struct kvm_nested_state), 1081ebbfef2fSLiran Alon VMSTATE_U64(hdr.vmx.vmcs12_pa, struct kvm_nested_state), 1082ebbfef2fSLiran Alon VMSTATE_U16(hdr.vmx.smm.flags, struct kvm_nested_state), 1083ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1084ebbfef2fSLiran Alon }, 1085ebbfef2fSLiran Alon .subsections = (const VMStateDescription*[]) { 1086ebbfef2fSLiran Alon &vmstate_vmx_vmcs12, 1087ebbfef2fSLiran Alon &vmstate_vmx_shadow_vmcs12, 1088ebbfef2fSLiran Alon NULL, 1089ebbfef2fSLiran Alon } 1090ebbfef2fSLiran Alon }; 1091ebbfef2fSLiran Alon 1092b16c0e20SPaolo Bonzini static bool svm_nested_state_needed(void *opaque) 1093b16c0e20SPaolo Bonzini { 1094b16c0e20SPaolo Bonzini struct kvm_nested_state *nested_state = opaque; 1095b16c0e20SPaolo Bonzini 1096b16c0e20SPaolo Bonzini /* 1097b16c0e20SPaolo Bonzini * HF_GUEST_MASK and HF2_GIF_MASK are already serialized 1098b16c0e20SPaolo Bonzini * via hflags and hflags2, all that's left is the opaque 1099b16c0e20SPaolo Bonzini * nested state blob. 1100b16c0e20SPaolo Bonzini */ 1101b16c0e20SPaolo Bonzini return (nested_state->format == KVM_STATE_NESTED_FORMAT_SVM && 1102b16c0e20SPaolo Bonzini nested_state->size > offsetof(struct kvm_nested_state, data)); 1103b16c0e20SPaolo Bonzini } 1104b16c0e20SPaolo Bonzini 1105b16c0e20SPaolo Bonzini static const VMStateDescription vmstate_svm_nested_state = { 1106b16c0e20SPaolo Bonzini .name = "cpu/kvm_nested_state/svm", 1107b16c0e20SPaolo Bonzini .version_id = 1, 1108b16c0e20SPaolo Bonzini .minimum_version_id = 1, 1109b16c0e20SPaolo Bonzini .needed = svm_nested_state_needed, 1110b16c0e20SPaolo Bonzini .fields = (VMStateField[]) { 1111b16c0e20SPaolo Bonzini VMSTATE_U64(hdr.svm.vmcb_pa, struct kvm_nested_state), 1112b16c0e20SPaolo Bonzini VMSTATE_UINT8_ARRAY(data.svm[0].vmcb12, 1113b16c0e20SPaolo Bonzini struct kvm_nested_state, 1114b16c0e20SPaolo Bonzini KVM_STATE_NESTED_SVM_VMCB_SIZE), 1115b16c0e20SPaolo Bonzini VMSTATE_END_OF_LIST() 1116b16c0e20SPaolo Bonzini } 1117b16c0e20SPaolo Bonzini }; 1118b16c0e20SPaolo Bonzini 1119ebbfef2fSLiran Alon static bool nested_state_needed(void *opaque) 1120ebbfef2fSLiran Alon { 1121ebbfef2fSLiran Alon X86CPU *cpu = opaque; 1122ebbfef2fSLiran Alon CPUX86State *env = &cpu->env; 1123ebbfef2fSLiran Alon 1124ebbfef2fSLiran Alon return (env->nested_state && 1125b16c0e20SPaolo Bonzini (vmx_nested_state_needed(env->nested_state) || 1126b16c0e20SPaolo Bonzini svm_nested_state_needed(env->nested_state))); 1127ebbfef2fSLiran Alon } 1128ebbfef2fSLiran Alon 1129ebbfef2fSLiran Alon static int nested_state_post_load(void *opaque, int version_id) 1130ebbfef2fSLiran Alon { 1131ebbfef2fSLiran Alon X86CPU *cpu = opaque; 1132ebbfef2fSLiran Alon CPUX86State *env = &cpu->env; 1133ebbfef2fSLiran Alon struct kvm_nested_state *nested_state = env->nested_state; 1134ebbfef2fSLiran Alon int min_nested_state_len = offsetof(struct kvm_nested_state, data); 1135ebbfef2fSLiran Alon int max_nested_state_len = kvm_max_nested_state_length(); 1136ebbfef2fSLiran Alon 1137ebbfef2fSLiran Alon /* 1138ebbfef2fSLiran Alon * If our kernel don't support setting nested state 1139ebbfef2fSLiran Alon * and we have received nested state from migration stream, 1140ebbfef2fSLiran Alon * we need to fail migration 1141ebbfef2fSLiran Alon */ 1142ebbfef2fSLiran Alon if (max_nested_state_len <= 0) { 1143ebbfef2fSLiran Alon error_report("Received nested state when kernel cannot restore it"); 1144ebbfef2fSLiran Alon return -EINVAL; 1145ebbfef2fSLiran Alon } 1146ebbfef2fSLiran Alon 1147ebbfef2fSLiran Alon /* 1148ebbfef2fSLiran Alon * Verify that the size of received nested_state struct 1149ebbfef2fSLiran Alon * at least cover required header and is not larger 1150ebbfef2fSLiran Alon * than the max size that our kernel support 1151ebbfef2fSLiran Alon */ 1152ebbfef2fSLiran Alon if (nested_state->size < min_nested_state_len) { 1153ebbfef2fSLiran Alon error_report("Received nested state size less than min: " 1154ebbfef2fSLiran Alon "len=%d, min=%d", 1155ebbfef2fSLiran Alon nested_state->size, min_nested_state_len); 1156ebbfef2fSLiran Alon return -EINVAL; 1157ebbfef2fSLiran Alon } 1158ebbfef2fSLiran Alon if (nested_state->size > max_nested_state_len) { 1159ebbfef2fSLiran Alon error_report("Recieved unsupported nested state size: " 1160ebbfef2fSLiran Alon "nested_state->size=%d, max=%d", 1161ebbfef2fSLiran Alon nested_state->size, max_nested_state_len); 1162ebbfef2fSLiran Alon return -EINVAL; 1163ebbfef2fSLiran Alon } 1164ebbfef2fSLiran Alon 1165ebbfef2fSLiran Alon /* Verify format is valid */ 1166ebbfef2fSLiran Alon if ((nested_state->format != KVM_STATE_NESTED_FORMAT_VMX) && 1167ebbfef2fSLiran Alon (nested_state->format != KVM_STATE_NESTED_FORMAT_SVM)) { 1168ebbfef2fSLiran Alon error_report("Received invalid nested state format: %d", 1169ebbfef2fSLiran Alon nested_state->format); 1170ebbfef2fSLiran Alon return -EINVAL; 1171ebbfef2fSLiran Alon } 1172ebbfef2fSLiran Alon 1173ebbfef2fSLiran Alon return 0; 1174ebbfef2fSLiran Alon } 1175ebbfef2fSLiran Alon 1176ebbfef2fSLiran Alon static const VMStateDescription vmstate_kvm_nested_state = { 1177ebbfef2fSLiran Alon .name = "cpu/kvm_nested_state", 1178ebbfef2fSLiran Alon .version_id = 1, 1179ebbfef2fSLiran Alon .minimum_version_id = 1, 1180ebbfef2fSLiran Alon .fields = (VMStateField[]) { 1181ebbfef2fSLiran Alon VMSTATE_U16(flags, struct kvm_nested_state), 1182ebbfef2fSLiran Alon VMSTATE_U16(format, struct kvm_nested_state), 1183ebbfef2fSLiran Alon VMSTATE_U32(size, struct kvm_nested_state), 1184ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1185ebbfef2fSLiran Alon }, 1186ebbfef2fSLiran Alon .subsections = (const VMStateDescription*[]) { 1187ebbfef2fSLiran Alon &vmstate_vmx_nested_state, 1188b16c0e20SPaolo Bonzini &vmstate_svm_nested_state, 1189ebbfef2fSLiran Alon NULL 1190ebbfef2fSLiran Alon } 1191ebbfef2fSLiran Alon }; 1192ebbfef2fSLiran Alon 1193ebbfef2fSLiran Alon static const VMStateDescription vmstate_nested_state = { 1194ebbfef2fSLiran Alon .name = "cpu/nested_state", 1195ebbfef2fSLiran Alon .version_id = 1, 1196ebbfef2fSLiran Alon .minimum_version_id = 1, 1197ebbfef2fSLiran Alon .needed = nested_state_needed, 1198ebbfef2fSLiran Alon .post_load = nested_state_post_load, 1199ebbfef2fSLiran Alon .fields = (VMStateField[]) { 1200ebbfef2fSLiran Alon VMSTATE_STRUCT_POINTER(env.nested_state, X86CPU, 1201ebbfef2fSLiran Alon vmstate_kvm_nested_state, 1202ebbfef2fSLiran Alon struct kvm_nested_state), 1203ebbfef2fSLiran Alon VMSTATE_END_OF_LIST() 1204ebbfef2fSLiran Alon } 1205ebbfef2fSLiran Alon }; 1206ebbfef2fSLiran Alon 1207ebbfef2fSLiran Alon #endif 1208ebbfef2fSLiran Alon 120987f8b626SAshok Raj static bool mcg_ext_ctl_needed(void *opaque) 121087f8b626SAshok Raj { 121187f8b626SAshok Raj X86CPU *cpu = opaque; 121287f8b626SAshok Raj CPUX86State *env = &cpu->env; 121387f8b626SAshok Raj return cpu->enable_lmce && env->mcg_ext_ctl; 121487f8b626SAshok Raj } 121587f8b626SAshok Raj 121687f8b626SAshok Raj static const VMStateDescription vmstate_mcg_ext_ctl = { 121787f8b626SAshok Raj .name = "cpu/mcg_ext_ctl", 121887f8b626SAshok Raj .version_id = 1, 121987f8b626SAshok Raj .minimum_version_id = 1, 122087f8b626SAshok Raj .needed = mcg_ext_ctl_needed, 122187f8b626SAshok Raj .fields = (VMStateField[]) { 122287f8b626SAshok Raj VMSTATE_UINT64(env.mcg_ext_ctl, X86CPU), 122387f8b626SAshok Raj VMSTATE_END_OF_LIST() 122487f8b626SAshok Raj } 122587f8b626SAshok Raj }; 122687f8b626SAshok Raj 1227a33a2cfeSPaolo Bonzini static bool spec_ctrl_needed(void *opaque) 1228a33a2cfeSPaolo Bonzini { 1229a33a2cfeSPaolo Bonzini X86CPU *cpu = opaque; 1230a33a2cfeSPaolo Bonzini CPUX86State *env = &cpu->env; 1231a33a2cfeSPaolo Bonzini 1232a33a2cfeSPaolo Bonzini return env->spec_ctrl != 0; 1233a33a2cfeSPaolo Bonzini } 1234a33a2cfeSPaolo Bonzini 1235a33a2cfeSPaolo Bonzini static const VMStateDescription vmstate_spec_ctrl = { 1236a33a2cfeSPaolo Bonzini .name = "cpu/spec_ctrl", 1237a33a2cfeSPaolo Bonzini .version_id = 1, 1238a33a2cfeSPaolo Bonzini .minimum_version_id = 1, 1239a33a2cfeSPaolo Bonzini .needed = spec_ctrl_needed, 1240a33a2cfeSPaolo Bonzini .fields = (VMStateField[]){ 1241a33a2cfeSPaolo Bonzini VMSTATE_UINT64(env.spec_ctrl, X86CPU), 1242a33a2cfeSPaolo Bonzini VMSTATE_END_OF_LIST() 1243a33a2cfeSPaolo Bonzini } 1244a33a2cfeSPaolo Bonzini }; 1245a33a2cfeSPaolo Bonzini 1246b77146e9SChao Peng static bool intel_pt_enable_needed(void *opaque) 1247b77146e9SChao Peng { 1248b77146e9SChao Peng X86CPU *cpu = opaque; 1249b77146e9SChao Peng CPUX86State *env = &cpu->env; 1250b77146e9SChao Peng int i; 1251b77146e9SChao Peng 1252b77146e9SChao Peng if (env->msr_rtit_ctrl || env->msr_rtit_status || 1253b77146e9SChao Peng env->msr_rtit_output_base || env->msr_rtit_output_mask || 1254b77146e9SChao Peng env->msr_rtit_cr3_match) { 1255b77146e9SChao Peng return true; 1256b77146e9SChao Peng } 1257b77146e9SChao Peng 1258b77146e9SChao Peng for (i = 0; i < MAX_RTIT_ADDRS; i++) { 1259b77146e9SChao Peng if (env->msr_rtit_addrs[i]) { 1260b77146e9SChao Peng return true; 1261b77146e9SChao Peng } 1262b77146e9SChao Peng } 1263b77146e9SChao Peng 1264b77146e9SChao Peng return false; 1265b77146e9SChao Peng } 1266b77146e9SChao Peng 1267b77146e9SChao Peng static const VMStateDescription vmstate_msr_intel_pt = { 1268b77146e9SChao Peng .name = "cpu/intel_pt", 1269b77146e9SChao Peng .version_id = 1, 1270b77146e9SChao Peng .minimum_version_id = 1, 1271b77146e9SChao Peng .needed = intel_pt_enable_needed, 1272b77146e9SChao Peng .fields = (VMStateField[]) { 1273b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_ctrl, X86CPU), 1274b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_status, X86CPU), 1275b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_output_base, X86CPU), 1276b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_output_mask, X86CPU), 1277b77146e9SChao Peng VMSTATE_UINT64(env.msr_rtit_cr3_match, X86CPU), 1278b77146e9SChao Peng VMSTATE_UINT64_ARRAY(env.msr_rtit_addrs, X86CPU, MAX_RTIT_ADDRS), 1279b77146e9SChao Peng VMSTATE_END_OF_LIST() 1280b77146e9SChao Peng } 1281b77146e9SChao Peng }; 1282b77146e9SChao Peng 1283cfeea0c0SKonrad Rzeszutek Wilk static bool virt_ssbd_needed(void *opaque) 1284cfeea0c0SKonrad Rzeszutek Wilk { 1285cfeea0c0SKonrad Rzeszutek Wilk X86CPU *cpu = opaque; 1286cfeea0c0SKonrad Rzeszutek Wilk CPUX86State *env = &cpu->env; 1287cfeea0c0SKonrad Rzeszutek Wilk 1288cfeea0c0SKonrad Rzeszutek Wilk return env->virt_ssbd != 0; 1289cfeea0c0SKonrad Rzeszutek Wilk } 1290cfeea0c0SKonrad Rzeszutek Wilk 1291cfeea0c0SKonrad Rzeszutek Wilk static const VMStateDescription vmstate_msr_virt_ssbd = { 1292cfeea0c0SKonrad Rzeszutek Wilk .name = "cpu/virt_ssbd", 1293cfeea0c0SKonrad Rzeszutek Wilk .version_id = 1, 1294cfeea0c0SKonrad Rzeszutek Wilk .minimum_version_id = 1, 1295cfeea0c0SKonrad Rzeszutek Wilk .needed = virt_ssbd_needed, 1296cfeea0c0SKonrad Rzeszutek Wilk .fields = (VMStateField[]){ 1297cfeea0c0SKonrad Rzeszutek Wilk VMSTATE_UINT64(env.virt_ssbd, X86CPU), 1298cfeea0c0SKonrad Rzeszutek Wilk VMSTATE_END_OF_LIST() 1299cfeea0c0SKonrad Rzeszutek Wilk } 1300cfeea0c0SKonrad Rzeszutek Wilk }; 1301cfeea0c0SKonrad Rzeszutek Wilk 1302fe441054SJan Kiszka static bool svm_npt_needed(void *opaque) 1303fe441054SJan Kiszka { 1304fe441054SJan Kiszka X86CPU *cpu = opaque; 1305fe441054SJan Kiszka CPUX86State *env = &cpu->env; 1306fe441054SJan Kiszka 1307fe441054SJan Kiszka return !!(env->hflags2 & HF2_NPT_MASK); 1308fe441054SJan Kiszka } 1309fe441054SJan Kiszka 1310fe441054SJan Kiszka static const VMStateDescription vmstate_svm_npt = { 1311fe441054SJan Kiszka .name = "cpu/svn_npt", 1312fe441054SJan Kiszka .version_id = 1, 1313fe441054SJan Kiszka .minimum_version_id = 1, 1314fe441054SJan Kiszka .needed = svm_npt_needed, 1315fe441054SJan Kiszka .fields = (VMStateField[]){ 1316fe441054SJan Kiszka VMSTATE_UINT64(env.nested_cr3, X86CPU), 1317fe441054SJan Kiszka VMSTATE_UINT32(env.nested_pg_mode, X86CPU), 1318fe441054SJan Kiszka VMSTATE_END_OF_LIST() 1319fe441054SJan Kiszka } 1320fe441054SJan Kiszka }; 1321fe441054SJan Kiszka 132289a44a10SPavel Dovgalyuk #ifndef TARGET_X86_64 132389a44a10SPavel Dovgalyuk static bool intel_efer32_needed(void *opaque) 132489a44a10SPavel Dovgalyuk { 132589a44a10SPavel Dovgalyuk X86CPU *cpu = opaque; 132689a44a10SPavel Dovgalyuk CPUX86State *env = &cpu->env; 132789a44a10SPavel Dovgalyuk 132889a44a10SPavel Dovgalyuk return env->efer != 0; 132989a44a10SPavel Dovgalyuk } 133089a44a10SPavel Dovgalyuk 133189a44a10SPavel Dovgalyuk static const VMStateDescription vmstate_efer32 = { 133289a44a10SPavel Dovgalyuk .name = "cpu/efer32", 133389a44a10SPavel Dovgalyuk .version_id = 1, 133489a44a10SPavel Dovgalyuk .minimum_version_id = 1, 133589a44a10SPavel Dovgalyuk .needed = intel_efer32_needed, 133689a44a10SPavel Dovgalyuk .fields = (VMStateField[]) { 133789a44a10SPavel Dovgalyuk VMSTATE_UINT64(env.efer, X86CPU), 133889a44a10SPavel Dovgalyuk VMSTATE_END_OF_LIST() 133989a44a10SPavel Dovgalyuk } 134089a44a10SPavel Dovgalyuk }; 134189a44a10SPavel Dovgalyuk #endif 134289a44a10SPavel Dovgalyuk 13432a9758c5SPaolo Bonzini static bool msr_tsx_ctrl_needed(void *opaque) 13442a9758c5SPaolo Bonzini { 13452a9758c5SPaolo Bonzini X86CPU *cpu = opaque; 13462a9758c5SPaolo Bonzini CPUX86State *env = &cpu->env; 13472a9758c5SPaolo Bonzini 13482a9758c5SPaolo Bonzini return env->features[FEAT_ARCH_CAPABILITIES] & ARCH_CAP_TSX_CTRL_MSR; 13492a9758c5SPaolo Bonzini } 13502a9758c5SPaolo Bonzini 13512a9758c5SPaolo Bonzini static const VMStateDescription vmstate_msr_tsx_ctrl = { 13522a9758c5SPaolo Bonzini .name = "cpu/msr_tsx_ctrl", 13532a9758c5SPaolo Bonzini .version_id = 1, 13542a9758c5SPaolo Bonzini .minimum_version_id = 1, 13552a9758c5SPaolo Bonzini .needed = msr_tsx_ctrl_needed, 13562a9758c5SPaolo Bonzini .fields = (VMStateField[]) { 13572a9758c5SPaolo Bonzini VMSTATE_UINT32(env.tsx_ctrl, X86CPU), 13582a9758c5SPaolo Bonzini VMSTATE_END_OF_LIST() 13592a9758c5SPaolo Bonzini } 13602a9758c5SPaolo Bonzini }; 13612a9758c5SPaolo Bonzini 136268bfd0adSMarcelo Tosatti VMStateDescription vmstate_x86_cpu = { 13630cb892aaSJuan Quintela .name = "cpu", 1364f56e3a14SAndreas Färber .version_id = 12, 136508b277acSDr. David Alan Gilbert .minimum_version_id = 11, 13660cb892aaSJuan Quintela .pre_save = cpu_pre_save, 13670cb892aaSJuan Quintela .post_load = cpu_post_load, 13680cb892aaSJuan Quintela .fields = (VMStateField[]) { 1369f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS), 1370f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eip, X86CPU), 1371f56e3a14SAndreas Färber VMSTATE_UINTTL(env.eflags, X86CPU), 1372f56e3a14SAndreas Färber VMSTATE_UINT32(env.hflags, X86CPU), 13730cb892aaSJuan Quintela /* FPU */ 1374f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpuc, X86CPU), 1375f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpus_vmstate, X86CPU), 1376f56e3a14SAndreas Färber VMSTATE_UINT16(env.fptag_vmstate, X86CPU), 1377f56e3a14SAndreas Färber VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU), 137846baa900SDr. David Alan Gilbert 137946baa900SDr. David Alan Gilbert VMSTATE_STRUCT_ARRAY(env.fpregs, X86CPU, 8, 0, vmstate_fpreg, FPReg), 13808dd3dca3Saurel32 1381f56e3a14SAndreas Färber VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6), 1382f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.ldt, X86CPU), 1383f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.tr, X86CPU), 1384f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.gdt, X86CPU), 1385f56e3a14SAndreas Färber VMSTATE_SEGMENT(env.idt, X86CPU), 1386468f6581SJuan Quintela 1387f56e3a14SAndreas Färber VMSTATE_UINT32(env.sysenter_cs, X86CPU), 1388f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_esp, X86CPU), 1389f56e3a14SAndreas Färber VMSTATE_UINTTL(env.sysenter_eip, X86CPU), 13908dd3dca3Saurel32 1391f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[0], X86CPU), 1392f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[2], X86CPU), 1393f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[3], X86CPU), 1394f56e3a14SAndreas Färber VMSTATE_UINTTL(env.cr[4], X86CPU), 1395f56e3a14SAndreas Färber VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8), 13960cb892aaSJuan Quintela /* MMU */ 1397f56e3a14SAndreas Färber VMSTATE_INT32(env.a20_mask, X86CPU), 13980cb892aaSJuan Quintela /* XMM */ 1399f56e3a14SAndreas Färber VMSTATE_UINT32(env.mxcsr, X86CPU), 1400a03c3e90SPaolo Bonzini VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, 0), 14018dd3dca3Saurel32 14028dd3dca3Saurel32 #ifdef TARGET_X86_64 1403f56e3a14SAndreas Färber VMSTATE_UINT64(env.efer, X86CPU), 1404f56e3a14SAndreas Färber VMSTATE_UINT64(env.star, X86CPU), 1405f56e3a14SAndreas Färber VMSTATE_UINT64(env.lstar, X86CPU), 1406f56e3a14SAndreas Färber VMSTATE_UINT64(env.cstar, X86CPU), 1407f56e3a14SAndreas Färber VMSTATE_UINT64(env.fmask, X86CPU), 1408f56e3a14SAndreas Färber VMSTATE_UINT64(env.kernelgsbase, X86CPU), 14098dd3dca3Saurel32 #endif 141008b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.smbase, X86CPU), 14118dd3dca3Saurel32 141208b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.pat, X86CPU), 141308b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.hflags2, X86CPU), 1414dd5e3b17Saliguori 141508b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.vm_hsave, X86CPU), 141608b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.vm_vmcb, X86CPU), 141708b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.tsc_offset, X86CPU), 141808b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.intercept, X86CPU), 141908b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_cr_read, X86CPU), 142008b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_cr_write, X86CPU), 142108b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_dr_read, X86CPU), 142208b277acSDr. David Alan Gilbert VMSTATE_UINT16(env.intercept_dr_write, X86CPU), 142308b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.intercept_exceptions, X86CPU), 142408b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.v_tpr, X86CPU), 1425dd5e3b17Saliguori /* MTRRs */ 142608b277acSDr. David Alan Gilbert VMSTATE_UINT64_ARRAY(env.mtrr_fixed, X86CPU, 11), 142708b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mtrr_deftype, X86CPU), 1428d8b5c67bSAlex Williamson VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, MSR_MTRRcap_VCNT, 8), 14290cb892aaSJuan Quintela /* KVM-related states */ 143008b277acSDr. David Alan Gilbert VMSTATE_INT32(env.interrupt_injected, X86CPU), 143108b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.mp_state, X86CPU), 143208b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.tsc, X86CPU), 1433fd13f23bSLiran Alon VMSTATE_INT32(env.exception_nr, X86CPU), 143408b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.soft_interrupt, X86CPU), 143508b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.nmi_injected, X86CPU), 143608b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.nmi_pending, X86CPU), 143708b277acSDr. David Alan Gilbert VMSTATE_UINT8(env.has_error_code, X86CPU), 143808b277acSDr. David Alan Gilbert VMSTATE_UINT32(env.sipi_vector, X86CPU), 14390cb892aaSJuan Quintela /* MCE */ 144008b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mcg_cap, X86CPU), 144108b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mcg_status, X86CPU), 144208b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.mcg_ctl, X86CPU), 144308b277acSDr. David Alan Gilbert VMSTATE_UINT64_ARRAY(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4), 14440cb892aaSJuan Quintela /* rdtscp */ 144508b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.tsc_aux, X86CPU), 14461a03675dSGlauber Costa /* KVM pvclock msr */ 144708b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.system_time_msr, X86CPU), 144808b277acSDr. David Alan Gilbert VMSTATE_UINT64(env.wall_clock_msr, X86CPU), 1449f1665b21SSheng Yang /* XSAVE related fields */ 1450f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xcr0, X86CPU, 12), 1451f56e3a14SAndreas Färber VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12), 1452b7711471SPaolo Bonzini VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, 0, 12), 14530cb892aaSJuan Quintela VMSTATE_END_OF_LIST() 1454a0fb002cSJan Kiszka /* The above list is not sorted /wrt version numbers, watch out! */ 1455f6584ee2SGleb Natapov }, 14565cd8cadaSJuan Quintela .subsections = (const VMStateDescription*[]) { 1457fd13f23bSLiran Alon &vmstate_exception_info, 14585cd8cadaSJuan Quintela &vmstate_async_pf_msr, 1459db5daafaSVitaly Kuznetsov &vmstate_async_pf_int_msr, 14605cd8cadaSJuan Quintela &vmstate_pv_eoi_msr, 14615cd8cadaSJuan Quintela &vmstate_steal_time_msr, 1462d645e132SMarcelo Tosatti &vmstate_poll_control_msr, 14635cd8cadaSJuan Quintela &vmstate_fpop_ip_dp, 14645cd8cadaSJuan Quintela &vmstate_msr_tsc_adjust, 14655cd8cadaSJuan Quintela &vmstate_msr_tscdeadline, 14665cd8cadaSJuan Quintela &vmstate_msr_ia32_misc_enable, 14675cd8cadaSJuan Quintela &vmstate_msr_ia32_feature_control, 14685cd8cadaSJuan Quintela &vmstate_msr_architectural_pmu, 14695cd8cadaSJuan Quintela &vmstate_mpx, 14705cd8cadaSJuan Quintela &vmstate_msr_hypercall_hypercall, 14715cd8cadaSJuan Quintela &vmstate_msr_hyperv_vapic, 14725cd8cadaSJuan Quintela &vmstate_msr_hyperv_time, 1473f2a53c9eSAndrey Smetanin &vmstate_msr_hyperv_crash, 147446eb8f98SAndrey Smetanin &vmstate_msr_hyperv_runtime, 1475866eea9aSAndrey Smetanin &vmstate_msr_hyperv_synic, 1476ff99aa64SAndrey Smetanin &vmstate_msr_hyperv_stimer, 1477ba6a4fd9SVitaly Kuznetsov &vmstate_msr_hyperv_reenlightenment, 14785cd8cadaSJuan Quintela &vmstate_avx512, 14795cd8cadaSJuan Quintela &vmstate_xss, 148065087997STao Xu &vmstate_umwait, 148136f96c4bSHaozhong Zhang &vmstate_tsc_khz, 1482e13713dbSLiran Alon &vmstate_msr_smi_count, 1483f74eefe0SHuaitong Han #ifdef TARGET_X86_64 1484f74eefe0SHuaitong Han &vmstate_pkru, 1485f74eefe0SHuaitong Han #endif 1486a33a2cfeSPaolo Bonzini &vmstate_spec_ctrl, 148787f8b626SAshok Raj &vmstate_mcg_ext_ctl, 1488b77146e9SChao Peng &vmstate_msr_intel_pt, 1489cfeea0c0SKonrad Rzeszutek Wilk &vmstate_msr_virt_ssbd, 1490fe441054SJan Kiszka &vmstate_svm_npt, 149189a44a10SPavel Dovgalyuk #ifndef TARGET_X86_64 149289a44a10SPavel Dovgalyuk &vmstate_efer32, 149389a44a10SPavel Dovgalyuk #endif 1494ebbfef2fSLiran Alon #ifdef CONFIG_KVM 1495ebbfef2fSLiran Alon &vmstate_nested_state, 1496ebbfef2fSLiran Alon #endif 14972a9758c5SPaolo Bonzini &vmstate_msr_tsx_ctrl, 14985cd8cadaSJuan Quintela NULL 1499dd5e3b17Saliguori } 15000cb892aaSJuan Quintela }; 1501