diff options
-rw-r--r-- | arch_init.c | 7 | ||||
-rw-r--r-- | bsd-user/main.c | 3 | ||||
-rw-r--r-- | hw/i386/pc_piix.c | 13 | ||||
-rw-r--r-- | include/hw/i386/pc.h | 29 | ||||
-rw-r--r-- | include/qemu/osdep.h | 9 | ||||
-rw-r--r-- | include/sysemu/arch_init.h | 1 | ||||
-rw-r--r-- | linux-user/main.c | 3 | ||||
-rw-r--r-- | target-i386/cpu.c | 62 | ||||
-rw-r--r-- | target-i386/cpu.h | 101 | ||||
-rw-r--r-- | target-i386/kvm.c | 451 | ||||
-rw-r--r-- | target-i386/translate.c | 6 | ||||
-rw-r--r-- | util/osdep.c | 9 | ||||
-rw-r--r-- | vl.c | 7 |
13 files changed, 401 insertions, 300 deletions
diff --git a/arch_init.c b/arch_init.c index 07f047fad4..fa059731ed 100644 --- a/arch_init.c +++ b/arch_init.c @@ -274,13 +274,6 @@ void do_smbios_option(QemuOpts *opts) #endif } -void cpudef_init(void) -{ -#if defined(cpudef_setup) - cpudef_setup(); /* parse cpu definitions in target config file */ -#endif -} - int kvm_available(void) { #ifdef CONFIG_KVM diff --git a/bsd-user/main.c b/bsd-user/main.c index 8e338c7f22..9f592be96f 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -753,9 +753,6 @@ int main(int argc, char **argv) } cpu_model = NULL; -#if defined(cpudef_setup) - cpudef_setup(); /* parse cpu definitions in target config file (TBD) */ -#endif optind = 1; for(;;) { diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 32918bb294..24e7042680 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -582,6 +582,7 @@ DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4, #define PC_COMPAT_1_3 \ + PC_CPU_MODEL_IDS("1.3.0") \ {\ .driver = "usb-tablet",\ .property = "usb_version",\ @@ -613,6 +614,7 @@ DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3, #define PC_COMPAT_1_2 \ + PC_CPU_MODEL_IDS("1.2.0") \ {\ .driver = "nec-usb-xhci",\ .property = "msi",\ @@ -651,6 +653,7 @@ DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2, #define PC_COMPAT_1_1 \ + PC_CPU_MODEL_IDS("1.1.0") \ {\ .driver = "virtio-scsi-pci",\ .property = "hotplug",\ @@ -693,6 +696,7 @@ DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2, #define PC_COMPAT_1_0 \ + PC_CPU_MODEL_IDS("1.0") \ {\ .driver = TYPE_ISA_FDC,\ .property = "check_media_rate",\ @@ -722,10 +726,14 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2, pc_i440fx_1_0_machine_options); +#define PC_COMPAT_0_15 \ + PC_CPU_MODEL_IDS("0.15") + static void pc_i440fx_0_15_machine_options(MachineClass *m) { pc_i440fx_1_0_machine_options(m); m->hw_version = "0.15"; + SET_MACHINE_COMPAT(m, PC_COMPAT_0_15); } DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2, @@ -733,6 +741,7 @@ DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2, #define PC_COMPAT_0_14 \ + PC_CPU_MODEL_IDS("0.14") \ {\ .driver = "virtio-blk-pci",\ .property = "event_idx",\ @@ -771,6 +780,7 @@ DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2, #define PC_COMPAT_0_13 \ + PC_CPU_MODEL_IDS("0.13") \ {\ .driver = TYPE_PCI_DEVICE,\ .property = "command_serr_enable",\ @@ -807,6 +817,7 @@ DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13, #define PC_COMPAT_0_12 \ + PC_CPU_MODEL_IDS("0.12") \ {\ .driver = "virtio-serial-pci",\ .property = "max_ports",\ @@ -841,6 +852,7 @@ DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13, #define PC_COMPAT_0_11 \ + PC_CPU_MODEL_IDS("0.11") \ {\ .driver = "virtio-blk-pci",\ .property = "vectors",\ @@ -871,6 +883,7 @@ DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13, #define PC_COMPAT_0_10 \ + PC_CPU_MODEL_IDS("0.10") \ {\ .driver = "virtio-blk-pci",\ .property = "class",\ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 367b6dbf0e..9ca23098bd 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -359,8 +359,29 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_2_5 \ HW_COMPAT_2_5 +/* Helper for setting model-id for CPU models that changed model-id + * depending on QEMU versions up to QEMU 2.4. + */ +#define PC_CPU_MODEL_IDS(v) \ + {\ + .driver = "qemu32-" TYPE_X86_CPU,\ + .property = "model-id",\ + .value = "QEMU Virtual CPU version " v,\ + },\ + {\ + .driver = "qemu64-" TYPE_X86_CPU,\ + .property = "model-id",\ + .value = "QEMU Virtual CPU version " v,\ + },\ + {\ + .driver = "athlon-" TYPE_X86_CPU,\ + .property = "model-id",\ + .value = "QEMU Virtual CPU version " v,\ + }, + #define PC_COMPAT_2_4 \ HW_COMPAT_2_4 \ + PC_CPU_MODEL_IDS("2.4.0") \ {\ .driver = "Haswell-" TYPE_X86_CPU,\ .property = "abm",\ @@ -431,6 +452,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_2_3 \ HW_COMPAT_2_3 \ + PC_CPU_MODEL_IDS("2.3.0") \ {\ .driver = TYPE_X86_CPU,\ .property = "arat",\ @@ -511,6 +533,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_2_2 \ HW_COMPAT_2_2 \ + PC_CPU_MODEL_IDS("2.3.0") \ {\ .driver = "kvm64" "-" TYPE_X86_CPU,\ .property = "vme",\ @@ -604,6 +627,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_2_1 \ HW_COMPAT_2_1 \ + PC_CPU_MODEL_IDS("2.1.0") \ {\ .driver = "coreduo" "-" TYPE_X86_CPU,\ .property = "vmx",\ @@ -616,6 +640,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); }, #define PC_COMPAT_2_0 \ + PC_CPU_MODEL_IDS("2.0.0") \ {\ .driver = "virtio-scsi-pci",\ .property = "any_layout",\ @@ -675,6 +700,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); }, #define PC_COMPAT_1_7 \ + PC_CPU_MODEL_IDS("1.7.0") \ {\ .driver = TYPE_USB_DEVICE,\ .property = "msos-desc",\ @@ -692,6 +718,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); }, #define PC_COMPAT_1_6 \ + PC_CPU_MODEL_IDS("1.6.0") \ {\ .driver = "e1000",\ .property = "mitigation",\ @@ -715,6 +742,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); }, #define PC_COMPAT_1_5 \ + PC_CPU_MODEL_IDS("1.5.0") \ {\ .driver = "Conroe-" TYPE_X86_CPU,\ .property = "model",\ @@ -758,6 +786,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); }, #define PC_COMPAT_1_4 \ + PC_CPU_MODEL_IDS("1.4.0") \ {\ .driver = "scsi-hd",\ .property = "discard_granularity",\ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 994bfa023a..693769403f 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -327,6 +327,15 @@ static inline void qemu_timersub(const struct timeval *val1, void qemu_set_cloexec(int fd); +/* Starting on QEMU 2.5, qemu_hw_version() returns "2.5+" by default + * instead of QEMU_VERSION, so setting hw_version on MachineClass + * is no longer mandatory. + * + * Do NOT change this string, or it will break compatibility on all + * machine classes that don't set hw_version. + */ +#define QEMU_HW_VERSION "2.5+" + /* QEMU "hardware version" setting. Used to replace code that exposed * QEMU_VERSION to guests in the past and need to keep compatibility. * Do not use qemu_hw_version() in new code. diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h index c38892fec6..d690dfabdf 100644 --- a/include/sysemu/arch_init.h +++ b/include/sysemu/arch_init.h @@ -30,7 +30,6 @@ extern const uint32_t arch_type; void select_soundhw(const char *optarg); void do_acpitable_option(const QemuOpts *opts); void do_smbios_option(QemuOpts *opts); -void cpudef_init(void); void audio_init(void); int kvm_available(void); int xen_available(void); diff --git a/linux-user/main.c b/linux-user/main.c index ba38aed431..95ed11d85c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4154,9 +4154,6 @@ int main(int argc, char **argv, char **envp) } cpu_model = NULL; -#if defined(cpudef_setup) - cpudef_setup(); /* parse cpu definitions in target config file (TBD) */ -#endif srand(time(NULL)); diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 05bf5ed2f0..895a386d3b 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -474,25 +474,32 @@ static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = { const ExtSaveArea x86_ext_save_areas[] = { [XSTATE_YMM_BIT] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX, - .offset = 0x240, .size = 0x100 }, + .offset = offsetof(X86XSaveArea, avx_state), + .size = sizeof(XSaveAVX) }, [XSTATE_BNDREGS_BIT] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, - .offset = 0x3c0, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, bndreg_state), + .size = sizeof(XSaveBNDREG) }, [XSTATE_BNDCSR_BIT] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, - .offset = 0x400, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, bndcsr_state), + .size = sizeof(XSaveBNDCSR) }, [XSTATE_OPMASK_BIT] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x440, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, opmask_state), + .size = sizeof(XSaveOpmask) }, [XSTATE_ZMM_Hi256_BIT] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x480, .size = 0x200 }, + .offset = offsetof(X86XSaveArea, zmm_hi256_state), + .size = sizeof(XSaveZMM_Hi256) }, [XSTATE_Hi16_ZMM_BIT] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x680, .size = 0x400 }, + .offset = offsetof(X86XSaveArea, hi16_zmm_state), + .size = sizeof(XSaveHi16_ZMM) }, [XSTATE_PKRU_BIT] = { .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU, - .offset = 0xA80, .size = 0x8 }, + .offset = offsetof(X86XSaveArea, pkru_state), + .size = sizeof(XSavePKRU) }, }; const char *get_register_name_32(unsigned int reg) @@ -703,6 +710,7 @@ static X86CPUDefinition builtin_x86_defs[] = { .features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM, .xlevel = 0x8000000A, + .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION, }, { .name = "phenom", @@ -799,6 +807,7 @@ static X86CPUDefinition builtin_x86_defs[] = { .features[FEAT_1_ECX] = CPUID_EXT_SSE3, .xlevel = 0x80000004, + .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION, }, { .name = "kvm32", @@ -895,6 +904,7 @@ static X86CPUDefinition builtin_x86_defs[] = { .features[FEAT_8000_0001_EDX] = CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, .xlevel = 0x80000008, + .model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION, }, { .name = "n270", @@ -2264,30 +2274,6 @@ void cpu_clear_apic_feature(CPUX86State *env) #endif /* !CONFIG_USER_ONLY */ -/* Initialize list of CPU models, filling some non-static fields if necessary - */ -void x86_cpudef_setup(void) -{ - int i, j; - static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" }; - - for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) { - X86CPUDefinition *def = &builtin_x86_defs[i]; - - /* Look for specific "cpudef" models that */ - /* have the QEMU version in .model_id */ - for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) { - if (strcmp(model_with_versions[j], def->name) == 0) { - pstrcpy(def->model_id, sizeof(def->model_id), - "QEMU Virtual CPU version "); - pstrcat(def->model_id, sizeof(def->model_id), - qemu_hw_version()); - break; - } - } - } -} - void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) @@ -2916,6 +2902,12 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp) } + cpu_exec_init(cs, &error_abort); + + if (tcg_enabled()) { + tcg_x86_init(); + } + #ifndef CONFIG_USER_ONLY qemu_register_reset(x86_cpu_machine_reset_cb, cpu); @@ -3102,10 +3094,8 @@ static void x86_cpu_initfn(Object *obj) X86CPUClass *xcc = X86_CPU_GET_CLASS(obj); CPUX86State *env = &cpu->env; FeatureWord w; - static int inited; cs->env_ptr = env; - cpu_exec_init(cs, &error_abort); object_property_add(obj, "family", "int", x86_cpuid_version_get_family, @@ -3151,12 +3141,6 @@ static void x86_cpu_initfn(Object *obj) } x86_cpu_load_def(cpu, xcc->cpu_def, &error_abort); - - /* init various static tables used in TCG mode */ - if (tcg_enabled() && !inited) { - inited = 1; - tcg_x86_init(); - } } static int64_t x86_cpu_get_arch_id(CPUState *cs) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 5cf2422efb..0426459bba 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -830,6 +830,101 @@ typedef struct { #define NB_OPMASK_REGS 8 +typedef union X86LegacyXSaveArea { + struct { + uint16_t fcw; + uint16_t fsw; + uint8_t ftw; + uint8_t reserved; + uint16_t fpop; + uint64_t fpip; + uint64_t fpdp; + uint32_t mxcsr; + uint32_t mxcsr_mask; + FPReg fpregs[8]; + uint8_t xmm_regs[16][16]; + }; + uint8_t data[512]; +} X86LegacyXSaveArea; + +typedef struct X86XSaveHeader { + uint64_t xstate_bv; + uint64_t xcomp_bv; + uint8_t reserved[48]; +} X86XSaveHeader; + +/* Ext. save area 2: AVX State */ +typedef struct XSaveAVX { + uint8_t ymmh[16][16]; +} XSaveAVX; + +/* Ext. save area 3: BNDREG */ +typedef struct XSaveBNDREG { + BNDReg bnd_regs[4]; +} XSaveBNDREG; + +/* Ext. save area 4: BNDCSR */ +typedef union XSaveBNDCSR { + BNDCSReg bndcsr; + uint8_t data[64]; +} XSaveBNDCSR; + +/* Ext. save area 5: Opmask */ +typedef struct XSaveOpmask { + uint64_t opmask_regs[NB_OPMASK_REGS]; +} XSaveOpmask; + +/* Ext. save area 6: ZMM_Hi256 */ +typedef struct XSaveZMM_Hi256 { + uint8_t zmm_hi256[16][32]; +} XSaveZMM_Hi256; + +/* Ext. save area 7: Hi16_ZMM */ +typedef struct XSaveHi16_ZMM { + uint8_t hi16_zmm[16][64]; +} XSaveHi16_ZMM; + +/* Ext. save area 9: PKRU state */ +typedef struct XSavePKRU { + uint32_t pkru; + uint32_t padding; +} XSavePKRU; + +typedef struct X86XSaveArea { + X86LegacyXSaveArea legacy; + X86XSaveHeader header; + + /* Extended save areas: */ + + /* AVX State: */ + XSaveAVX avx_state; + uint8_t padding[960 - 576 - sizeof(XSaveAVX)]; + /* MPX State: */ + XSaveBNDREG bndreg_state; + XSaveBNDCSR bndcsr_state; + /* AVX-512 State: */ + XSaveOpmask opmask_state; + XSaveZMM_Hi256 zmm_hi256_state; + XSaveHi16_ZMM hi16_zmm_state; + /* PKRU State: */ + XSavePKRU pkru_state; +} X86XSaveArea; + +QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, avx_state) != 0x240); +QEMU_BUILD_BUG_ON(sizeof(XSaveAVX) != 0x100); +QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndreg_state) != 0x3c0); +QEMU_BUILD_BUG_ON(sizeof(XSaveBNDREG) != 0x40); +QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndcsr_state) != 0x400); +QEMU_BUILD_BUG_ON(sizeof(XSaveBNDCSR) != 0x40); +QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, opmask_state) != 0x440); +QEMU_BUILD_BUG_ON(sizeof(XSaveOpmask) != 0x40); +QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, zmm_hi256_state) != 0x480); +QEMU_BUILD_BUG_ON(sizeof(XSaveZMM_Hi256) != 0x200); +QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, hi16_zmm_state) != 0x680); +QEMU_BUILD_BUG_ON(sizeof(XSaveHi16_ZMM) != 0x400); +QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, pkru_state) != 0xA80); +QEMU_BUILD_BUG_ON(sizeof(XSavePKRU) != 0x8); + typedef enum TPRAccess { TPR_ACCESS_READ, TPR_ACCESS_WRITE, @@ -1029,6 +1124,8 @@ typedef struct CPUX86State { TPRAccess tpr_access_type; } CPUX86State; +struct kvm_msrs; + /** * X86CPU: * @env: #CPUX86State @@ -1081,6 +1178,8 @@ struct X86CPU { struct DeviceState *apic_state; struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram; Notifier machine_done; + + struct kvm_msrs *kvm_msr_buf; }; static inline X86CPU *x86_env_get_cpu(CPUX86State *env) @@ -1130,7 +1229,6 @@ X86CPU *cpu_x86_init(const char *cpu_model); X86CPU *cpu_x86_create(const char *cpu_model, Error **errp); int cpu_x86_exec(CPUState *cpu); void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf); -void x86_cpudef_setup(void); int cpu_x86_support_mca_broadcast(CPUX86State *env); int cpu_get_pic_interrupt(CPUX86State *s); @@ -1308,7 +1406,6 @@ uint64_t cpu_get_tsc(CPUX86State *env); #define cpu_exec cpu_x86_exec #define cpu_signal_handler cpu_x86_signal_handler #define cpu_list x86_cpu_list -#define cpudef_setup x86_cpudef_setup /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _ksmap diff --git a/target-i386/kvm.c b/target-i386/kvm.c index c76e7bbc89..7b3667a089 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -57,6 +57,10 @@ #define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_SYSTEM_TIME 0x12 +/* A 4096-byte buffer can hold the 8-byte kvm_msrs header, plus + * 255 kvm_msr_entry structs */ +#define MSR_BUF_SIZE 4096 + #ifndef BUS_MCEERR_AR #define BUS_MCEERR_AR 4 #endif @@ -914,6 +918,7 @@ int kvm_arch_init_vcpu(CPUState *cs) if (has_xsave) { env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); } + cpu->kvm_msr_buf = g_malloc0(MSR_BUF_SIZE); if (env->features[FEAT_1_EDX] & CPUID_MTRR) { has_msr_mtrr = true; @@ -1307,12 +1312,34 @@ static int kvm_put_fpu(X86CPU *cpu) #define XSAVE_Hi16_ZMM 416 #define XSAVE_PKRU 672 +#define XSAVE_BYTE_OFFSET(word_offset) \ + ((word_offset) * sizeof(((struct kvm_xsave *)0)->region[0])) + +#define ASSERT_OFFSET(word_offset, field) \ + QEMU_BUILD_BUG_ON(XSAVE_BYTE_OFFSET(word_offset) != \ + offsetof(X86XSaveArea, field)) + +ASSERT_OFFSET(XSAVE_FCW_FSW, legacy.fcw); +ASSERT_OFFSET(XSAVE_FTW_FOP, legacy.ftw); +ASSERT_OFFSET(XSAVE_CWD_RIP, legacy.fpip); +ASSERT_OFFSET(XSAVE_CWD_RDP, legacy.fpdp); +ASSERT_OFFSET(XSAVE_MXCSR, legacy.mxcsr); +ASSERT_OFFSET(XSAVE_ST_SPACE, legacy.fpregs); +ASSERT_OFFSET(XSAVE_XMM_SPACE, legacy.xmm_regs); +ASSERT_OFFSET(XSAVE_XSTATE_BV, header.xstate_bv); +ASSERT_OFFSET(XSAVE_YMMH_SPACE, avx_state); +ASSERT_OFFSET(XSAVE_BNDREGS, bndreg_state); +ASSERT_OFFSET(XSAVE_BNDCSR, bndcsr_state); +ASSERT_OFFSET(XSAVE_OPMASK, opmask_state); +ASSERT_OFFSET(XSAVE_ZMM_Hi256, zmm_hi256_state); +ASSERT_OFFSET(XSAVE_Hi16_ZMM, hi16_zmm_state); +ASSERT_OFFSET(XSAVE_PKRU, pkru_state); + static int kvm_put_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct kvm_xsave* xsave = env->kvm_xsave_buf; + X86XSaveArea *xsave = env->kvm_xsave_buf; uint16_t cwd, swd, twd; - uint8_t *xmm, *ymmh, *zmmh; int i, r; if (!has_xsave) { @@ -1327,25 +1354,26 @@ static int kvm_put_xsave(X86CPU *cpu) for (i = 0; i < 8; ++i) { twd |= (!env->fptags[i]) << i; } - xsave->region[XSAVE_FCW_FSW] = (uint32_t)(swd << 16) + cwd; - xsave->region[XSAVE_FTW_FOP] = (uint32_t)(env->fpop << 16) + twd; - memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip)); - memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp)); - memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs, + xsave->legacy.fcw = cwd; + xsave->legacy.fsw = swd; + xsave->legacy.ftw = twd; + xsave->legacy.fpop = env->fpop; + xsave->legacy.fpip = env->fpip; + xsave->legacy.fpdp = env->fpdp; + memcpy(&xsave->legacy.fpregs, env->fpregs, sizeof env->fpregs); - xsave->region[XSAVE_MXCSR] = env->mxcsr; - *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv; - memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs, + xsave->legacy.mxcsr = env->mxcsr; + xsave->header.xstate_bv = env->xstate_bv; + memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs, sizeof env->bnd_regs); - memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs, - sizeof(env->bndcs_regs)); - memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs, + xsave->bndcsr_state.bndcsr = env->bndcs_regs; + memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs, sizeof env->opmask_regs); - xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; - ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; - zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; - for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { + for (i = 0; i < CPU_NB_REGS; i++) { + uint8_t *xmm = xsave->legacy.xmm_regs[i]; + uint8_t *ymmh = xsave->avx_state.ymmh[i]; + uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i]; stq_p(xmm, env->xmm_regs[i].ZMM_Q(0)); stq_p(xmm+8, env->xmm_regs[i].ZMM_Q(1)); stq_p(ymmh, env->xmm_regs[i].ZMM_Q(2)); @@ -1357,9 +1385,9 @@ static int kvm_put_xsave(X86CPU *cpu) } #ifdef TARGET_X86_64 - memcpy(&xsave->region[XSAVE_Hi16_ZMM], &env->xmm_regs[16], + memcpy(&xsave->hi16_zmm_state.hi16_zmm, &env->xmm_regs[16], 16 * sizeof env->xmm_regs[16]); - memcpy(&xsave->region[XSAVE_PKRU], &env->pkru, sizeof env->pkru); + memcpy(&xsave->pkru_state, &env->pkru, sizeof env->pkru); #endif r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave); return r; @@ -1431,35 +1459,38 @@ static int kvm_put_sregs(X86CPU *cpu) return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs); } -static void kvm_msr_entry_set(struct kvm_msr_entry *entry, - uint32_t index, uint64_t value) +static void kvm_msr_buf_reset(X86CPU *cpu) { + memset(cpu->kvm_msr_buf, 0, MSR_BUF_SIZE); +} + +static void kvm_msr_entry_add(X86CPU *cpu, uint32_t index, uint64_t value) +{ + struct kvm_msrs *msrs = cpu->kvm_msr_buf; + void *limit = ((void *)msrs) + MSR_BUF_SIZE; + struct kvm_msr_entry *entry = &msrs->entries[msrs->nmsrs]; + + assert((void *)(entry + 1) <= limit); + entry->index = index; entry->reserved = 0; entry->data = value; + msrs->nmsrs++; } static int kvm_put_tscdeadline_msr(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct { - struct kvm_msrs info; - struct kvm_msr_entry entries[1]; - } msr_data; - struct kvm_msr_entry *msrs = msr_data.entries; int ret; if (!has_msr_tsc_deadline) { return 0; } - kvm_msr_entry_set(&msrs[0], MSR_IA32_TSCDEADLINE, env->tsc_deadline); - - msr_data.info = (struct kvm_msrs) { - .nmsrs = 1, - }; + kvm_msr_buf_reset(cpu); + kvm_msr_entry_add(cpu, MSR_IA32_TSCDEADLINE, env->tsc_deadline); - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf); if (ret < 0) { return ret; } @@ -1476,24 +1507,17 @@ static int kvm_put_tscdeadline_msr(X86CPU *cpu) */ static int kvm_put_msr_feature_control(X86CPU *cpu) { - struct { - struct kvm_msrs info; - struct kvm_msr_entry entry; - } msr_data; int ret; if (!has_msr_feature_control) { return 0; } - kvm_msr_entry_set(&msr_data.entry, MSR_IA32_FEATURE_CONTROL, + kvm_msr_buf_reset(cpu); + kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL, cpu->env.msr_ia32_feature_control); - msr_data.info = (struct kvm_msrs) { - .nmsrs = 1, - }; - - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf); if (ret < 0) { return ret; } @@ -1505,49 +1529,46 @@ static int kvm_put_msr_feature_control(X86CPU *cpu) static int kvm_put_msrs(X86CPU *cpu, int level) { CPUX86State *env = &cpu->env; - struct { - struct kvm_msrs info; - struct kvm_msr_entry entries[150]; - } msr_data; - struct kvm_msr_entry *msrs = msr_data.entries; - int n = 0, i; + int i; int ret; - kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs); - kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp); - kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip); - kvm_msr_entry_set(&msrs[n++], MSR_PAT, env->pat); + kvm_msr_buf_reset(cpu); + + kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_CS, env->sysenter_cs); + kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_ESP, env->sysenter_esp); + kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_EIP, env->sysenter_eip); + kvm_msr_entry_add(cpu, MSR_PAT, env->pat); if (has_msr_star) { - kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star); + kvm_msr_entry_add(cpu, MSR_STAR, env->star); } if (has_msr_hsave_pa) { - kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave); + kvm_msr_entry_add(cpu, MSR_VM_HSAVE_PA, env->vm_hsave); } if (has_msr_tsc_aux) { - kvm_msr_entry_set(&msrs[n++], MSR_TSC_AUX, env->tsc_aux); + kvm_msr_entry_add(cpu, MSR_TSC_AUX, env->tsc_aux); } if (has_msr_tsc_adjust) { - kvm_msr_entry_set(&msrs[n++], MSR_TSC_ADJUST, env->tsc_adjust); + kvm_msr_entry_add(cpu, MSR_TSC_ADJUST, env->tsc_adjust); } if (has_msr_misc_enable) { - kvm_msr_entry_set(&msrs[n++], MSR_IA32_MISC_ENABLE, + kvm_msr_entry_add(cpu, MSR_IA32_MISC_ENABLE, env->msr_ia32_misc_enable); } if (has_msr_smbase) { - kvm_msr_entry_set(&msrs[n++], MSR_IA32_SMBASE, env->smbase); + kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, env->smbase); } if (has_msr_bndcfgs) { - kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs); + kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, env->msr_bndcfgs); } if (has_msr_xss) { - kvm_msr_entry_set(&msrs[n++], MSR_IA32_XSS, env->xss); + kvm_msr_entry_add(cpu, MSR_IA32_XSS, env->xss); } #ifdef TARGET_X86_64 if (lm_capable_kernel) { - kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar); - kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase); - kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask); - kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar); + kvm_msr_entry_add(cpu, MSR_CSTAR, env->cstar); + kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase); + kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask); + kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar); } #endif /* @@ -1555,91 +1576,85 @@ static int kvm_put_msrs(X86CPU *cpu, int level) * for normal writeback. Limit them to reset or full state updates. */ if (level >= KVM_PUT_RESET_STATE) { - kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc); - kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, - env->system_time_msr); - kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr); + kvm_msr_entry_add(cpu, MSR_IA32_TSC, env->tsc); + kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, env->system_time_msr); + kvm_msr_entry_add(cpu, MSR_KVM_WALL_CLOCK, env->wall_clock_msr); if (has_msr_async_pf_en) { - kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN, - env->async_pf_en_msr); + kvm_msr_entry_add(cpu, MSR_KVM_ASYNC_PF_EN, env->async_pf_en_msr); } if (has_msr_pv_eoi_en) { - kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN, - env->pv_eoi_en_msr); + kvm_msr_entry_add(cpu, MSR_KVM_PV_EOI_EN, env->pv_eoi_en_msr); } if (has_msr_kvm_steal_time) { - kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME, - env->steal_time_msr); + kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr); } if (has_msr_architectural_pmu) { /* Stop the counter. */ - kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL, 0); - kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL, 0); + kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0); + kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0); /* Set the counter values. */ for (i = 0; i < MAX_FIXED_COUNTERS; i++) { - kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR0 + i, + kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i, env->msr_fixed_counters[i]); } for (i = 0; i < num_architectural_pmu_counters; i++) { - kvm_msr_entry_set(&msrs[n++], MSR_P6_PERFCTR0 + i, + kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i, env->msr_gp_counters[i]); - kvm_msr_entry_set(&msrs[n++], MSR_P6_EVNTSEL0 + i, + kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i, env->msr_gp_evtsel[i]); } - kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_STATUS, + kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, env->msr_global_status); - kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_OVF_CTRL, + kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, env->msr_global_ovf_ctrl); /* Now start the PMU. */ - kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL, + kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, env->msr_fixed_ctr_ctrl); - kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL, + kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, env->msr_global_ctrl); } if (has_msr_hv_hypercall) { - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, + kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID, env->msr_hv_guest_os_id); - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, + kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL, env->msr_hv_hypercall); } if (has_msr_hv_vapic) { - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, + kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE, env->msr_hv_vapic); } if (has_msr_hv_tsc) { - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC, - env->msr_hv_tsc); + kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, env->msr_hv_tsc); } if (has_msr_hv_crash) { int j; for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++) - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_P0 + j, + kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_P0 + j, env->msr_hv_crash_params[j]); - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_CRASH_CTL, + kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_CTL, HV_X64_MSR_CRASH_CTL_NOTIFY); } if (has_msr_hv_runtime) { - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME, - env->msr_hv_runtime); + kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, env->msr_hv_runtime); } if (cpu->hyperv_synic) { int j; - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SCONTROL, + kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL, env->msr_hv_synic_control); - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SVERSION, + kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION, env->msr_hv_synic_version); - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SIEFP, + kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP, env->msr_hv_synic_evt_page); - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SIMP, + kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP, env->msr_hv_synic_msg_page); for (j = 0; j < ARRAY_SIZE(env->msr_hv_synic_sint); j++) { - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_SINT0 + j, + kvm_msr_entry_add(cpu, HV_X64_MSR_SINT0 + j, env->msr_hv_synic_sint[j]); } } @@ -1647,44 +1662,33 @@ static int kvm_put_msrs(X86CPU *cpu, int level) int j; for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_config); j++) { - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_CONFIG + j*2, + kvm_msr_entry_add(cpu, HV_X64_MSR_STIMER0_CONFIG + j * 2, env->msr_hv_stimer_config[j]); } for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_count); j++) { - kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_STIMER0_COUNT + j*2, + kvm_msr_entry_add(cpu, HV_X64_MSR_STIMER0_COUNT + j * 2, env->msr_hv_stimer_count[j]); } } if (has_msr_mtrr) { - kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix64K_00000, env->mtrr_fixed[0]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix16K_80000, env->mtrr_fixed[1]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]); + kvm_msr_entry_add(cpu, MSR_MTRRdefType, env->mtrr_deftype); + kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, env->mtrr_fixed[0]); + kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, env->mtrr_fixed[1]); + kvm_msr_entry_add(cpu, MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]); for (i = 0; i < MSR_MTRRcap_VCNT; i++) { - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRphysBase(i), env->mtrr_var[i].base); - kvm_msr_entry_set(&msrs[n++], - MSR_MTRRphysMask(i), env->mtrr_var[i].mask); + kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i), + env->mtrr_var[i].base); + kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), + env->mtrr_var[i].mask); } } @@ -1694,23 +1698,19 @@ static int kvm_put_msrs(X86CPU *cpu, int level) if (env->mcg_cap) { int i; - kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status); - kvm_msr_entry_set(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl); + kvm_msr_entry_add(cpu, MSR_MCG_STATUS, env->mcg_status); + kvm_msr_entry_add(cpu, MSR_MCG_CTL, env->mcg_ctl); for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) { - kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]); + kvm_msr_entry_add(cpu, MSR_MC0_CTL + i, env->mce_banks[i]); } } - msr_data.info = (struct kvm_msrs) { - .nmsrs = n, - }; - - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data); + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf); if (ret < 0) { return ret; } - assert(ret == n); + assert(ret == cpu->kvm_msr_buf->nmsrs); return 0; } @@ -1748,9 +1748,8 @@ static int kvm_get_fpu(X86CPU *cpu) static int kvm_get_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct kvm_xsave* xsave = env->kvm_xsave_buf; + X86XSaveArea *xsave = env->kvm_xsave_buf; int ret, i; - const uint8_t *xmm, *ymmh, *zmmh; uint16_t cwd, swd, twd; if (!has_xsave) { @@ -1762,33 +1761,32 @@ static int kvm_get_xsave(X86CPU *cpu) return ret; } - cwd = (uint16_t)xsave->region[XSAVE_FCW_FSW]; - swd = (uint16_t)(xsave->region[XSAVE_FCW_FSW] >> 16); - twd = (uint16_t)xsave->region[XSAVE_FTW_FOP]; - env->fpop = (uint16_t)(xsave->region[XSAVE_FTW_FOP] >> 16); + cwd = xsave->legacy.fcw; + swd = xsave->legacy.fsw; + twd = xsave->legacy.ftw; + env->fpop = xsave->legacy.fpop; env->fpstt = (swd >> 11) & 7; env->fpus = swd; env->fpuc = cwd; for (i = 0; i < 8; ++i) { env->fptags[i] = !((twd >> i) & 1); } - memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip)); - memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp)); - env->mxcsr = xsave->region[XSAVE_MXCSR]; - memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE], + env->fpip = xsave->legacy.fpip; + env->fpdp = xsave->legacy.fpdp; + env->mxcsr = xsave->legacy.mxcsr; + memcpy(env->fpregs, &xsave->legacy.fpregs, sizeof env->fpregs); - env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; - memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS], + env->xstate_bv = xsave->header.xstate_bv; + memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs, sizeof env->bnd_regs); - memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR], - sizeof(env->bndcs_regs)); - memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK], + env->bndcs_regs = xsave->bndcsr_state.bndcsr; + memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs, sizeof env->opmask_regs); - xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; - ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; - zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; - for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { + for (i = 0; i < CPU_NB_REGS; i++) { + uint8_t *xmm = xsave->legacy.xmm_regs[i]; + uint8_t *ymmh = xsave->avx_state.ymmh[i]; + uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i]; env->xmm_regs[i].ZMM_Q(0) = ldq_p(xmm); env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm+8); env->xmm_regs[i].ZMM_Q(2) = ldq_p(ymmh); @@ -1800,9 +1798,9 @@ static int kvm_get_xsave(X86CPU *cpu) } #ifdef TARGET_X86_64 - memcpy(&env->xmm_regs[16], &xsave->region[XSAVE_Hi16_ZMM], + memcpy(&env->xmm_regs[16], &xsave->hi16_zmm_state.hi16_zmm, 16 * sizeof env->xmm_regs[16]); - memcpy(&env->pkru, &xsave->region[XSAVE_PKRU], sizeof env->pkru); + memcpy(&env->pkru, &xsave->pkru_state, sizeof env->pkru); #endif return 0; } @@ -1923,125 +1921,122 @@ static int kvm_get_sregs(X86CPU *cpu) static int kvm_get_msrs(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct { - struct kvm_msrs info; - struct kvm_msr_entry entries[150]; - } msr_data; - struct kvm_msr_entry *msrs = msr_data.entries; - int ret, i, n; - - n = 0; - msrs[n++].index = MSR_IA32_SYSENTER_CS; - msrs[n++].index = MSR_IA32_SYSENTER_ESP; - msrs[n++].index = MSR_IA32_SYSENTER_EIP; - msrs[n++].index = MSR_PAT; + struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries; + int ret, i; + + kvm_msr_buf_reset(cpu); + + kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_CS, 0); + kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_ESP, 0); + kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_EIP, 0); + kvm_msr_entry_add(cpu, MSR_PAT, 0); if (has_msr_star) { - msrs[n++].index = MSR_STAR; + kvm_msr_entry_add(cpu, MSR_STAR, 0); } if (has_msr_hsave_pa) { - msrs[n++].index = MSR_VM_HSAVE_PA; + kvm_msr_entry_add(cpu, MSR_VM_HSAVE_PA, 0); } if (has_msr_tsc_aux) { - msrs[n++].index = MSR_TSC_AUX; + kvm_msr_entry_add(cpu, MSR_TSC_AUX, 0); } if (has_msr_tsc_adjust) { - msrs[n++].index = MSR_TSC_ADJUST; + kvm_msr_entry_add(cpu, MSR_TSC_ADJUST, 0); } if (has_msr_tsc_deadline) { - msrs[n++].index = MSR_IA32_TSCDEADLINE; + kvm_msr_entry_add(cpu, MSR_IA32_TSCDEADLINE, 0); } if (has_msr_misc_enable) { - msrs[n++].index = MSR_IA32_MISC_ENABLE; + kvm_msr_entry_add(cpu, MSR_IA32_MISC_ENABLE, 0); } if (has_msr_smbase) { - msrs[n++].index = MSR_IA32_SMBASE; + kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, 0); } if (has_msr_feature_control) { - msrs[n++].index = MSR_IA32_FEATURE_CONTROL; + kvm_msr_entry_add(cpu, MSR_IA32_FEATURE_CONTROL, 0); } if (has_msr_bndcfgs) { - msrs[n++].index = MSR_IA32_BNDCFGS; + kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, 0); } if (has_msr_xss) { - msrs[n++].index = MSR_IA32_XSS; + kvm_msr_entry_add(cpu, MSR_IA32_XSS, 0); } if (!env->tsc_valid) { - msrs[n++].index = MSR_IA32_TSC; + kvm_msr_entry_add(cpu, MSR_IA32_TSC, 0); env->tsc_valid = !runstate_is_running(); } #ifdef TARGET_X86_64 if (lm_capable_kernel) { - msrs[n++].index = MSR_CSTAR; - msrs[n++].index = MSR_KERNELGSBASE; - msrs[n++].index = MSR_FMASK; - msrs[n++].index = MSR_LSTAR; + kvm_msr_entry_add(cpu, MSR_CSTAR, 0); + kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, 0); + kvm_msr_entry_add(cpu, MSR_FMASK, 0); + kvm_msr_entry_add(cpu, MSR_LSTAR, 0); } #endif - msrs[n++].index = MSR_KVM_SYSTEM_TIME; - msrs[n++].index = MSR_KVM_WALL_CLOCK; + kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, 0); + kvm_msr_entry_add(cpu, MSR_KVM_WALL_CLOCK, 0); if (has_msr_async_pf_en) { - msrs[n++].index = MSR_KVM_ASYNC_PF_EN; + kvm_msr_entry_add(cpu, MSR_KVM_ASYNC_PF_EN, 0); } if (has_msr_pv_eoi_en) { - msrs[n++].index = MSR_KVM_PV_EOI_EN; + kvm_msr_entry_add(cpu, MSR_KVM_PV_EOI_EN, 0); } if (has_msr_kvm_steal_time) { - msrs[n++].index = MSR_KVM_STEAL_TIME; + kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, 0); } if (has_msr_architectural_pmu) { - msrs[n++].index = MSR_CORE_PERF_FIXED_CTR_CTRL; - msrs[n++].index = MSR_CORE_PERF_GLOBAL_CTRL; - msrs[n++].index = MSR_CORE_PERF_GLOBAL_STATUS; - msrs[n++].index = MSR_CORE_PERF_GLOBAL_OVF_CTRL; + kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0); + kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0); + kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, 0); + kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0); for (i = 0; i < MAX_FIXED_COUNTERS; i++) { - msrs[n++].index = MSR_CORE_PERF_FIXED_CTR0 + i; + kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i, 0); } for (i = 0; i < num_architectural_pmu_counters; i++) { - msrs[n++].index = MSR_P6_PERFCTR0 + i; - msrs[n++].index = MSR_P6_EVNTSEL0 + i; + kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i, 0); + kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i, 0); } } if (env->mcg_cap) { - msrs[n++].index = MSR_MCG_STATUS; - msrs[n++].index = MSR_MCG_CTL; + kvm_msr_entry_add(cpu, MSR_MCG_STATUS, 0); + kvm_msr_entry_add(cpu, MSR_MCG_CTL, 0); for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) { - msrs[n++].index = MSR_MC0_CTL + i; + kvm_msr_entry_add(cpu, MSR_MC0_CTL + i, 0); } } if (has_msr_hv_hypercall) { - msrs[n++].index = HV_X64_MSR_HYPERCALL; - msrs[n++].index = HV_X64_MSR_GUEST_OS_ID; + kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL, 0); + kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID, 0); } if (has_msr_hv_vapic) { - msrs[n++].index = HV_X64_MSR_APIC_ASSIST_PAGE; + kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE, 0); } if (has_msr_hv_tsc) { - msrs[n++].index = HV_X64_MSR_REFERENCE_TSC; + kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, 0); } if (has_msr_hv_crash) { int j; for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++) { - msrs[n++].index = HV_X64_MSR_CRASH_P0 + j; + kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_P0 + j, 0); } } if (has_msr_hv_runtime) { - msrs[n++].index = HV_X64_MSR_VP_RUNTIME; + kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, 0); } if (cpu->hyperv_synic) { uint32_t msr; - msrs[n++].index = HV_X64_MSR_SCONTROL; - msrs[n++].index = HV_X64_MSR_SVERSION; - msrs[n++].index = HV_X64_MSR_SIEFP; - msrs[n++].index = HV_X64_MSR_SIMP; + kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL, 0); + kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION, 0); + kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP, 0); + kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP, 0); for (msr = HV_X64_MSR_SINT0; msr <= HV_X64_MSR_SINT15; msr++) { - msrs[n++].index = msr; + kvm_msr_entry_add(cpu, msr, 0); } } if (has_msr_hv_stimer) { @@ -2049,38 +2044,34 @@ static int kvm_get_msrs(X86CPU *cpu) for (msr = HV_X64_MSR_STIMER0_CONFIG; msr <= HV_X64_MSR_STIMER3_COUNT; msr++) { - msrs[n++].index = msr; + kvm_msr_entry_add(cpu, msr, 0); } } if (has_msr_mtrr) { - msrs[n++].index = MSR_MTRRdefType; - msrs[n++].index = MSR_MTRRfix64K_00000; - msrs[n++].index = MSR_MTRRfix16K_80000; - msrs[n++].index = MSR_MTRRfix16K_A0000; - msrs[n++].index = MSR_MTRRfix4K_C0000; - msrs[n++].index = MSR_MTRRfix4K_C8000; - msrs[n++].index = MSR_MTRRfix4K_D0000; - msrs[n++].index = MSR_MTRRfix4K_D8000; - msrs[n++].index = MSR_MTRRfix4K_E0000; - msrs[n++].index = MSR_MTRRfix4K_E8000; - msrs[n++].index = MSR_MTRRfix4K_F0000; - msrs[n++].index = MSR_MTRRfix4K_F8000; + kvm_msr_entry_add(cpu, MSR_MTRRdefType, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix16K_A0000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C0000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C8000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D0000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D8000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E0000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E8000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, 0); + kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, 0); for (i = 0; i < MSR_MTRRcap_VCNT; i++) { - msrs[n++].index = MSR_MTRRphysBase(i); - msrs[n++].index = MSR_MTRRphysMask(i); + kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i), 0); + kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), 0); } } - msr_data.info = (struct kvm_msrs) { - .nmsrs = n, - }; - - ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data); + ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf); if (ret < 0) { return ret; } - assert(ret == n); + assert(ret == cpu->kvm_msr_buf->nmsrs); for (i = 0; i < ret; i++) { uint32_t index = msrs[i].index; switch (index) { diff --git a/target-i386/translate.c b/target-i386/translate.c index 731b10de06..bf33e6b353 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -8144,6 +8144,12 @@ void tcg_x86_init(void) "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" }; int i; + static bool initialized; + + if (initialized) { + return; + } + initialized = true; cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); cpu_cc_op = tcg_global_mem_new_i32(cpu_env, diff --git a/util/osdep.c b/util/osdep.c index d56d071111..9a7a439e13 100644 --- a/util/osdep.c +++ b/util/osdep.c @@ -44,14 +44,7 @@ extern int madvise(caddr_t, size_t, int); static bool fips_enabled = false; -/* Starting on QEMU 2.5, qemu_hw_version() returns "2.5+" by default - * instead of QEMU_VERSION, so setting hw_version on MachineClass - * is no longer mandatory. - * - * Do NOT change this string, or it will break compatibility on all - * machine classes that don't set hw_version. - */ -static const char *hw_version = "2.5+"; +static const char *hw_version = QEMU_HW_VERSION; int socket_set_cork(int fd, int v) { @@ -4047,13 +4047,6 @@ int main(int argc, char **argv, char **envp) qemu_set_hw_version(machine_class->hw_version); } - /* Init CPU def lists, based on config - * - Must be called after all the qemu_read_config_file() calls - * - Must be called before list_cpus() - * - Must be called before machine_class->init() - */ - cpudef_init(); - if (cpu_model && is_help_option(cpu_model)) { list_cpus(stdout, &fprintf, cpu_model); exit(0); |