qemu/target-i386/machine.c
<<
>>
Prefs
   1#include "hw/hw.h"
   2#include "hw/boards.h"
   3#include "hw/i386/pc.h"
   4#include "hw/isa/isa.h"
   5
   6#include "cpu.h"
   7#include "sysemu/kvm.h"
   8
   9static const VMStateDescription vmstate_segment = {
  10    .name = "segment",
  11    .version_id = 1,
  12    .minimum_version_id = 1,
  13    .minimum_version_id_old = 1,
  14    .fields      = (VMStateField []) {
  15        VMSTATE_UINT32(selector, SegmentCache),
  16        VMSTATE_UINTTL(base, SegmentCache),
  17        VMSTATE_UINT32(limit, SegmentCache),
  18        VMSTATE_UINT32(flags, SegmentCache),
  19        VMSTATE_END_OF_LIST()
  20    }
  21};
  22
  23#define VMSTATE_SEGMENT(_field, _state) {                            \
  24    .name       = (stringify(_field)),                               \
  25    .size       = sizeof(SegmentCache),                              \
  26    .vmsd       = &vmstate_segment,                                  \
  27    .flags      = VMS_STRUCT,                                        \
  28    .offset     = offsetof(_state, _field)                           \
  29            + type_check(SegmentCache,typeof_field(_state, _field))  \
  30}
  31
  32#define VMSTATE_SEGMENT_ARRAY(_field, _state, _n)                    \
  33    VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_segment, SegmentCache)
  34
  35static const VMStateDescription vmstate_xmm_reg = {
  36    .name = "xmm_reg",
  37    .version_id = 1,
  38    .minimum_version_id = 1,
  39    .minimum_version_id_old = 1,
  40    .fields      = (VMStateField []) {
  41        VMSTATE_UINT64(XMM_Q(0), XMMReg),
  42        VMSTATE_UINT64(XMM_Q(1), XMMReg),
  43        VMSTATE_END_OF_LIST()
  44    }
  45};
  46
  47#define VMSTATE_XMM_REGS(_field, _state, _n)                         \
  48    VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_xmm_reg, XMMReg)
  49
  50/* YMMH format is the same as XMM */
  51static const VMStateDescription vmstate_ymmh_reg = {
  52    .name = "ymmh_reg",
  53    .version_id = 1,
  54    .minimum_version_id = 1,
  55    .minimum_version_id_old = 1,
  56    .fields      = (VMStateField []) {
  57        VMSTATE_UINT64(XMM_Q(0), XMMReg),
  58        VMSTATE_UINT64(XMM_Q(1), XMMReg),
  59        VMSTATE_END_OF_LIST()
  60    }
  61};
  62
  63#define VMSTATE_YMMH_REGS_VARS(_field, _state, _n, _v)                         \
  64    VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_ymmh_reg, XMMReg)
  65
  66static const VMStateDescription vmstate_mtrr_var = {
  67    .name = "mtrr_var",
  68    .version_id = 1,
  69    .minimum_version_id = 1,
  70    .minimum_version_id_old = 1,
  71    .fields      = (VMStateField []) {
  72        VMSTATE_UINT64(base, MTRRVar),
  73        VMSTATE_UINT64(mask, MTRRVar),
  74        VMSTATE_END_OF_LIST()
  75    }
  76};
  77
  78#define VMSTATE_MTRR_VARS(_field, _state, _n, _v)                    \
  79    VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar)
  80
  81static void put_fpreg_error(QEMUFile *f, void *opaque, size_t size)
  82{
  83    fprintf(stderr, "call put_fpreg() with invalid arguments\n");
  84    exit(0);
  85}
  86
  87/* XXX: add that in a FPU generic layer */
  88union x86_longdouble {
  89    uint64_t mant;
  90    uint16_t exp;
  91};
  92
  93#define MANTD1(fp)      (fp & ((1LL << 52) - 1))
  94#define EXPBIAS1 1023
  95#define EXPD1(fp)       ((fp >> 52) & 0x7FF)
  96#define SIGND1(fp)      ((fp >> 32) & 0x80000000)
  97
  98static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
  99{
 100    int e;
 101    /* mantissa */
 102    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
 103    /* exponent + sign */
 104    e = EXPD1(temp) - EXPBIAS1 + 16383;
 105    e |= SIGND1(temp) >> 16;
 106    p->exp = e;
 107}
 108
 109static int get_fpreg(QEMUFile *f, void *opaque, size_t size)
 110{
 111    FPReg *fp_reg = opaque;
 112    uint64_t mant;
 113    uint16_t exp;
 114
 115    qemu_get_be64s(f, &mant);
 116    qemu_get_be16s(f, &exp);
 117    fp_reg->d = cpu_set_fp80(mant, exp);
 118    return 0;
 119}
 120
 121static void put_fpreg(QEMUFile *f, void *opaque, size_t size)
 122{
 123    FPReg *fp_reg = opaque;
 124    uint64_t mant;
 125    uint16_t exp;
 126    /* we save the real CPU data (in case of MMX usage only 'mant'
 127       contains the MMX register */
 128    cpu_get_fp80(&mant, &exp, fp_reg->d);
 129    qemu_put_be64s(f, &mant);
 130    qemu_put_be16s(f, &exp);
 131}
 132
 133static const VMStateInfo vmstate_fpreg = {
 134    .name = "fpreg",
 135    .get  = get_fpreg,
 136    .put  = put_fpreg,
 137};
 138
 139static int get_fpreg_1_mmx(QEMUFile *f, void *opaque, size_t size)
 140{
 141    union x86_longdouble *p = opaque;
 142    uint64_t mant;
 143
 144    qemu_get_be64s(f, &mant);
 145    p->mant = mant;
 146    p->exp = 0xffff;
 147    return 0;
 148}
 149
 150static const VMStateInfo vmstate_fpreg_1_mmx = {
 151    .name = "fpreg_1_mmx",
 152    .get  = get_fpreg_1_mmx,
 153    .put  = put_fpreg_error,
 154};
 155
 156static int get_fpreg_1_no_mmx(QEMUFile *f, void *opaque, size_t size)
 157{
 158    union x86_longdouble *p = opaque;
 159    uint64_t mant;
 160
 161    qemu_get_be64s(f, &mant);
 162    fp64_to_fp80(p, mant);
 163    return 0;
 164}
 165
 166static const VMStateInfo vmstate_fpreg_1_no_mmx = {
 167    .name = "fpreg_1_no_mmx",
 168    .get  = get_fpreg_1_no_mmx,
 169    .put  = put_fpreg_error,
 170};
 171
 172static bool fpregs_is_0(void *opaque, int version_id)
 173{
 174    X86CPU *cpu = opaque;
 175    CPUX86State *env = &cpu->env;
 176
 177    return (env->fpregs_format_vmstate == 0);
 178}
 179
 180static bool fpregs_is_1_mmx(void *opaque, int version_id)
 181{
 182    X86CPU *cpu = opaque;
 183    CPUX86State *env = &cpu->env;
 184    int guess_mmx;
 185
 186    guess_mmx = ((env->fptag_vmstate == 0xff) &&
 187                 (env->fpus_vmstate & 0x3800) == 0);
 188    return (guess_mmx && (env->fpregs_format_vmstate == 1));
 189}
 190
 191static bool fpregs_is_1_no_mmx(void *opaque, int version_id)
 192{
 193    X86CPU *cpu = opaque;
 194    CPUX86State *env = &cpu->env;
 195    int guess_mmx;
 196
 197    guess_mmx = ((env->fptag_vmstate == 0xff) &&
 198                 (env->fpus_vmstate & 0x3800) == 0);
 199    return (!guess_mmx && (env->fpregs_format_vmstate == 1));
 200}
 201
 202#define VMSTATE_FP_REGS(_field, _state, _n)                               \
 203    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_0, vmstate_fpreg, FPReg), \
 204    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_mmx, vmstate_fpreg_1_mmx, FPReg), \
 205    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_no_mmx, vmstate_fpreg_1_no_mmx, FPReg)
 206
 207static bool version_is_5(void *opaque, int version_id)
 208{
 209    return version_id == 5;
 210}
 211
 212#ifdef TARGET_X86_64
 213static bool less_than_7(void *opaque, int version_id)
 214{
 215    return version_id < 7;
 216}
 217
 218static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
 219{
 220    uint64_t *v = pv;
 221    *v = qemu_get_be32(f);
 222    return 0;
 223}
 224
 225static void put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
 226{
 227    uint64_t *v = pv;
 228    qemu_put_be32(f, *v);
 229}
 230
 231static const VMStateInfo vmstate_hack_uint64_as_uint32 = {
 232    .name = "uint64_as_uint32",
 233    .get  = get_uint64_as_uint32,
 234    .put  = put_uint64_as_uint32,
 235};
 236
 237#define VMSTATE_HACK_UINT32(_f, _s, _t)                                  \
 238    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint64_as_uint32, uint64_t)
 239#endif
 240
 241static void cpu_pre_save(void *opaque)
 242{
 243    X86CPU *cpu = opaque;
 244    CPUX86State *env = &cpu->env;
 245    int i;
 246
 247    /* FPU */
 248    env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
 249    env->fptag_vmstate = 0;
 250    for(i = 0; i < 8; i++) {
 251        env->fptag_vmstate |= ((!env->fptags[i]) << i);
 252    }
 253
 254    env->fpregs_format_vmstate = 0;
 255
 256    /*
 257     * Real mode guest segments register DPL should be zero.
 258     * Older KVM version were setting it wrongly.
 259     * Fixing it will allow live migration to host with unrestricted guest
 260     * support (otherwise the migration will fail with invalid guest state
 261     * error).
 262     */
 263    if (!(env->cr[0] & CR0_PE_MASK) &&
 264        (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) {
 265        env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK);
 266        env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK);
 267        env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK);
 268        env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK);
 269        env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK);
 270        env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK);
 271    }
 272
 273}
 274
 275static int cpu_post_load(void *opaque, int version_id)
 276{
 277    X86CPU *cpu = opaque;
 278    CPUX86State *env = &cpu->env;
 279    int i;
 280
 281    /*
 282     * Real mode guest segments register DPL should be zero.
 283     * Older KVM version were setting it wrongly.
 284     * Fixing it will allow live migration from such host that don't have
 285     * restricted guest support to a host with unrestricted guest support
 286     * (otherwise the migration will fail with invalid guest state
 287     * error).
 288     */
 289    if (!(env->cr[0] & CR0_PE_MASK) &&
 290        (env->segs[R_CS].flags >> DESC_DPL_SHIFT & 3) != 0) {
 291        env->segs[R_CS].flags &= ~(env->segs[R_CS].flags & DESC_DPL_MASK);
 292        env->segs[R_DS].flags &= ~(env->segs[R_DS].flags & DESC_DPL_MASK);
 293        env->segs[R_ES].flags &= ~(env->segs[R_ES].flags & DESC_DPL_MASK);
 294        env->segs[R_FS].flags &= ~(env->segs[R_FS].flags & DESC_DPL_MASK);
 295        env->segs[R_GS].flags &= ~(env->segs[R_GS].flags & DESC_DPL_MASK);
 296        env->segs[R_SS].flags &= ~(env->segs[R_SS].flags & DESC_DPL_MASK);
 297    }
 298
 299    /* XXX: restore FPU round state */
 300    env->fpstt = (env->fpus_vmstate >> 11) & 7;
 301    env->fpus = env->fpus_vmstate & ~0x3800;
 302    env->fptag_vmstate ^= 0xff;
 303    for(i = 0; i < 8; i++) {
 304        env->fptags[i] = (env->fptag_vmstate >> i) & 1;
 305    }
 306
 307    cpu_breakpoint_remove_all(env, BP_CPU);
 308    cpu_watchpoint_remove_all(env, BP_CPU);
 309    for (i = 0; i < DR7_MAX_BP; i++) {
 310        hw_breakpoint_insert(env, i);
 311    }
 312    tlb_flush(env, 1);
 313
 314    return 0;
 315}
 316
 317static bool async_pf_msr_needed(void *opaque)
 318{
 319    X86CPU *cpu = opaque;
 320
 321    return cpu->env.async_pf_en_msr != 0;
 322}
 323
 324static bool pv_eoi_msr_needed(void *opaque)
 325{
 326    X86CPU *cpu = opaque;
 327
 328    return cpu->env.pv_eoi_en_msr != 0;
 329}
 330
 331static bool steal_time_msr_needed(void *opaque)
 332{
 333    CPUX86State *cpu = opaque;
 334
 335    return cpu->steal_time_msr != 0;
 336}
 337
 338static const VMStateDescription vmstate_steal_time_msr = {
 339    .name = "cpu/steal_time_msr",
 340    .version_id = 1,
 341    .minimum_version_id = 1,
 342    .minimum_version_id_old = 1,
 343    .fields      = (VMStateField []) {
 344        VMSTATE_UINT64(steal_time_msr, CPUX86State),
 345        VMSTATE_END_OF_LIST()
 346    }
 347};
 348
 349static const VMStateDescription vmstate_async_pf_msr = {
 350    .name = "cpu/async_pf_msr",
 351    .version_id = 1,
 352    .minimum_version_id = 1,
 353    .minimum_version_id_old = 1,
 354    .fields      = (VMStateField []) {
 355        VMSTATE_UINT64(env.async_pf_en_msr, X86CPU),
 356        VMSTATE_END_OF_LIST()
 357    }
 358};
 359
 360static const VMStateDescription vmstate_pv_eoi_msr = {
 361    .name = "cpu/async_pv_eoi_msr",
 362    .version_id = 1,
 363    .minimum_version_id = 1,
 364    .minimum_version_id_old = 1,
 365    .fields      = (VMStateField []) {
 366        VMSTATE_UINT64(env.pv_eoi_en_msr, X86CPU),
 367        VMSTATE_END_OF_LIST()
 368    }
 369};
 370
 371static bool fpop_ip_dp_needed(void *opaque)
 372{
 373    X86CPU *cpu = opaque;
 374    CPUX86State *env = &cpu->env;
 375
 376    return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0;
 377}
 378
 379static const VMStateDescription vmstate_fpop_ip_dp = {
 380    .name = "cpu/fpop_ip_dp",
 381    .version_id = 1,
 382    .minimum_version_id = 1,
 383    .minimum_version_id_old = 1,
 384    .fields      = (VMStateField []) {
 385        VMSTATE_UINT16(env.fpop, X86CPU),
 386        VMSTATE_UINT64(env.fpip, X86CPU),
 387        VMSTATE_UINT64(env.fpdp, X86CPU),
 388        VMSTATE_END_OF_LIST()
 389    }
 390};
 391
 392static bool tsc_adjust_needed(void *opaque)
 393{
 394    X86CPU *cpu = opaque;
 395    CPUX86State *env = &cpu->env;
 396
 397    return env->tsc_adjust != 0;
 398}
 399
 400static const VMStateDescription vmstate_msr_tsc_adjust = {
 401    .name = "cpu/msr_tsc_adjust",
 402    .version_id = 1,
 403    .minimum_version_id = 1,
 404    .minimum_version_id_old = 1,
 405    .fields      = (VMStateField[]) {
 406        VMSTATE_UINT64(env.tsc_adjust, X86CPU),
 407        VMSTATE_END_OF_LIST()
 408    }
 409};
 410
 411static bool tscdeadline_needed(void *opaque)
 412{
 413    X86CPU *cpu = opaque;
 414    CPUX86State *env = &cpu->env;
 415
 416    return env->tsc_deadline != 0;
 417}
 418
 419static const VMStateDescription vmstate_msr_tscdeadline = {
 420    .name = "cpu/msr_tscdeadline",
 421    .version_id = 1,
 422    .minimum_version_id = 1,
 423    .minimum_version_id_old = 1,
 424    .fields      = (VMStateField []) {
 425        VMSTATE_UINT64(env.tsc_deadline, X86CPU),
 426        VMSTATE_END_OF_LIST()
 427    }
 428};
 429
 430static bool misc_enable_needed(void *opaque)
 431{
 432    X86CPU *cpu = opaque;
 433    CPUX86State *env = &cpu->env;
 434
 435    return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT;
 436}
 437
 438static const VMStateDescription vmstate_msr_ia32_misc_enable = {
 439    .name = "cpu/msr_ia32_misc_enable",
 440    .version_id = 1,
 441    .minimum_version_id = 1,
 442    .minimum_version_id_old = 1,
 443    .fields      = (VMStateField []) {
 444        VMSTATE_UINT64(env.msr_ia32_misc_enable, X86CPU),
 445        VMSTATE_END_OF_LIST()
 446    }
 447};
 448
 449const VMStateDescription vmstate_x86_cpu = {
 450    .name = "cpu",
 451    .version_id = 12,
 452    .minimum_version_id = 3,
 453    .minimum_version_id_old = 3,
 454    .pre_save = cpu_pre_save,
 455    .post_load = cpu_post_load,
 456    .fields      = (VMStateField []) {
 457        VMSTATE_UINTTL_ARRAY(env.regs, X86CPU, CPU_NB_REGS),
 458        VMSTATE_UINTTL(env.eip, X86CPU),
 459        VMSTATE_UINTTL(env.eflags, X86CPU),
 460        VMSTATE_UINT32(env.hflags, X86CPU),
 461        /* FPU */
 462        VMSTATE_UINT16(env.fpuc, X86CPU),
 463        VMSTATE_UINT16(env.fpus_vmstate, X86CPU),
 464        VMSTATE_UINT16(env.fptag_vmstate, X86CPU),
 465        VMSTATE_UINT16(env.fpregs_format_vmstate, X86CPU),
 466        VMSTATE_FP_REGS(env.fpregs, X86CPU, 8),
 467
 468        VMSTATE_SEGMENT_ARRAY(env.segs, X86CPU, 6),
 469        VMSTATE_SEGMENT(env.ldt, X86CPU),
 470        VMSTATE_SEGMENT(env.tr, X86CPU),
 471        VMSTATE_SEGMENT(env.gdt, X86CPU),
 472        VMSTATE_SEGMENT(env.idt, X86CPU),
 473
 474        VMSTATE_UINT32(env.sysenter_cs, X86CPU),
 475#ifdef TARGET_X86_64
 476        /* Hack: In v7 size changed from 32 to 64 bits on x86_64 */
 477        VMSTATE_HACK_UINT32(env.sysenter_esp, X86CPU, less_than_7),
 478        VMSTATE_HACK_UINT32(env.sysenter_eip, X86CPU, less_than_7),
 479        VMSTATE_UINTTL_V(env.sysenter_esp, X86CPU, 7),
 480        VMSTATE_UINTTL_V(env.sysenter_eip, X86CPU, 7),
 481#else
 482        VMSTATE_UINTTL(env.sysenter_esp, X86CPU),
 483        VMSTATE_UINTTL(env.sysenter_eip, X86CPU),
 484#endif
 485
 486        VMSTATE_UINTTL(env.cr[0], X86CPU),
 487        VMSTATE_UINTTL(env.cr[2], X86CPU),
 488        VMSTATE_UINTTL(env.cr[3], X86CPU),
 489        VMSTATE_UINTTL(env.cr[4], X86CPU),
 490        VMSTATE_UINTTL_ARRAY(env.dr, X86CPU, 8),
 491        /* MMU */
 492        VMSTATE_INT32(env.a20_mask, X86CPU),
 493        /* XMM */
 494        VMSTATE_UINT32(env.mxcsr, X86CPU),
 495        VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, CPU_NB_REGS),
 496
 497#ifdef TARGET_X86_64
 498        VMSTATE_UINT64(env.efer, X86CPU),
 499        VMSTATE_UINT64(env.star, X86CPU),
 500        VMSTATE_UINT64(env.lstar, X86CPU),
 501        VMSTATE_UINT64(env.cstar, X86CPU),
 502        VMSTATE_UINT64(env.fmask, X86CPU),
 503        VMSTATE_UINT64(env.kernelgsbase, X86CPU),
 504#endif
 505        VMSTATE_UINT32_V(env.smbase, X86CPU, 4),
 506
 507        VMSTATE_UINT64_V(env.pat, X86CPU, 5),
 508        VMSTATE_UINT32_V(env.hflags2, X86CPU, 5),
 509
 510        VMSTATE_UINT32_TEST(parent_obj.halted, X86CPU, version_is_5),
 511        VMSTATE_UINT64_V(env.vm_hsave, X86CPU, 5),
 512        VMSTATE_UINT64_V(env.vm_vmcb, X86CPU, 5),
 513        VMSTATE_UINT64_V(env.tsc_offset, X86CPU, 5),
 514        VMSTATE_UINT64_V(env.intercept, X86CPU, 5),
 515        VMSTATE_UINT16_V(env.intercept_cr_read, X86CPU, 5),
 516        VMSTATE_UINT16_V(env.intercept_cr_write, X86CPU, 5),
 517        VMSTATE_UINT16_V(env.intercept_dr_read, X86CPU, 5),
 518        VMSTATE_UINT16_V(env.intercept_dr_write, X86CPU, 5),
 519        VMSTATE_UINT32_V(env.intercept_exceptions, X86CPU, 5),
 520        VMSTATE_UINT8_V(env.v_tpr, X86CPU, 5),
 521        /* MTRRs */
 522        VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8),
 523        VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8),
 524        VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, 8, 8),
 525        /* KVM-related states */
 526        VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9),
 527        VMSTATE_UINT32_V(env.mp_state, X86CPU, 9),
 528        VMSTATE_UINT64_V(env.tsc, X86CPU, 9),
 529        VMSTATE_INT32_V(env.exception_injected, X86CPU, 11),
 530        VMSTATE_UINT8_V(env.soft_interrupt, X86CPU, 11),
 531        VMSTATE_UINT8_V(env.nmi_injected, X86CPU, 11),
 532        VMSTATE_UINT8_V(env.nmi_pending, X86CPU, 11),
 533        VMSTATE_UINT8_V(env.has_error_code, X86CPU, 11),
 534        VMSTATE_UINT32_V(env.sipi_vector, X86CPU, 11),
 535        /* MCE */
 536        VMSTATE_UINT64_V(env.mcg_cap, X86CPU, 10),
 537        VMSTATE_UINT64_V(env.mcg_status, X86CPU, 10),
 538        VMSTATE_UINT64_V(env.mcg_ctl, X86CPU, 10),
 539        VMSTATE_UINT64_ARRAY_V(env.mce_banks, X86CPU, MCE_BANKS_DEF * 4, 10),
 540        /* rdtscp */
 541        VMSTATE_UINT64_V(env.tsc_aux, X86CPU, 11),
 542        /* KVM pvclock msr */
 543        VMSTATE_UINT64_V(env.system_time_msr, X86CPU, 11),
 544        VMSTATE_UINT64_V(env.wall_clock_msr, X86CPU, 11),
 545        /* XSAVE related fields */
 546        VMSTATE_UINT64_V(env.xcr0, X86CPU, 12),
 547        VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12),
 548        VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, CPU_NB_REGS, 12),
 549        VMSTATE_END_OF_LIST()
 550        /* The above list is not sorted /wrt version numbers, watch out! */
 551    },
 552    .subsections = (VMStateSubsection []) {
 553        {
 554            .vmsd = &vmstate_async_pf_msr,
 555            .needed = async_pf_msr_needed,
 556        } , {
 557            .vmsd = &vmstate_pv_eoi_msr,
 558            .needed = pv_eoi_msr_needed,
 559        } , {
 560            .vmsd = &vmstate_steal_time_msr,
 561            .needed = steal_time_msr_needed,
 562        } , {
 563            .vmsd = &vmstate_fpop_ip_dp,
 564            .needed = fpop_ip_dp_needed,
 565        }, {
 566            .vmsd = &vmstate_msr_tsc_adjust,
 567            .needed = tsc_adjust_needed,
 568        }, {
 569            .vmsd = &vmstate_msr_tscdeadline,
 570            .needed = tscdeadline_needed,
 571        }, {
 572            .vmsd = &vmstate_msr_ia32_misc_enable,
 573            .needed = misc_enable_needed,
 574        } , {
 575            /* empty */
 576        }
 577    }
 578};
 579