X86 queue, 2016-05-23

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJXQ4i7AAoJECgHk2+YTcWmkhsQAIELcp/4Kj/9TBqurmicXrBm
 sEfLGThc94NZv6tDNUg4d96x83263RJPUsJqOP7TGSavO5xWD8J4A1yf8x6tI71l
 /kr064fZzYZGgKyaIvFBqmNT8uy3CVZ1+5algaYh4pOBD3y0hrTBmwB2vIHZeKDC
 6ljLuOVV2/n3SlhthK4Me9DiNPTwmMolfq2EG+5jBHmFXnbXRmApXaiX4a3qNvI+
 Aqz9btyJgTReepPcpuxF3o/h+Dx0JgC1gT4bPkIDV0wx00adUWufhRqc3D1QaOBr
 AREMSpeepuHNrkPpc7ITvyMK9q+bW8OzB0koXQW6Q50DtM7DRsxkqsr3TDvkSGG+
 ZyxsL6UdDoSKwJaDcbkhRL82P6U+MvfMBLMbo4V+S1728maUVRx74Ah+axRVX6wb
 hWtEYPvFUKp03lY82hXDoZJC+WLu+mhuAqS6a74/OG47lV2V61X8i3zrZ54RVHMh
 1fkr4MXkPvrRTH+ifjJlH6leWg5JA6OCPPMqO0fujUIxlMGA9QAHK6Fs0ReKEUyy
 WNXQ/CMfHcZv3WIJWH2NEBTJHfQwP4KWM6nIoO8Z4WT7tFpqUGULabJ9jt5t3NB5
 lW586UT6pCnqUwh89yTYLg0+Q+rmgmIlAwjVL6q0tRXXL98kosng2jgzlu7gpSBJ
 2lXFSzoqr+Ux3GbNF6E4
 =Rh0Q
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging

X86 queue, 2016-05-23

# gpg: Signature made Mon 23 May 2016 23:48:27 BST using RSA key ID 984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"

* remotes/ehabkost/tags/x86-pull-request:
  target-i386: kvm: Eliminate kvm_msr_entry_set()
  target-i386: kvm: Simplify MSR setting functions
  target-i386: kvm: Simplify MSR array construction
  target-i386: kvm: Increase MSR_BUF_SIZE
  target-i386: kvm: Allocate kvm_msrs struct once per VCPU
  target-i386: Call cpu_exec_init() on realize
  target-i386: Move TCG initialization to realize time
  target-i386: Move TCG initialization check to tcg_x86_init()
  cpu: Eliminate cpudef_init(), cpudef_setup()
  target-i386: Set constant model_id for qemu64/qemu32/athlon
  pc: Set CPU model-id on compat_props for pc <= 2.4
  osdep: Move default qemu_hw_version() value to a macro
  target-i386: kvm: Use X86XSaveArea struct for xsave save/load
  target-i386: Use xsave structs for ext_save_area
  target-i386: Define structs for layout of xsave area

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-05-24 13:06:32 +01:00
commit 287db79df8
13 changed files with 400 additions and 299 deletions

View File

@ -274,13 +274,6 @@ void do_smbios_option(QemuOpts *opts)
#endif #endif
} }
void cpudef_init(void)
{
#if defined(cpudef_setup)
cpudef_setup(); /* parse cpu definitions in target config file */
#endif
}
int kvm_available(void) int kvm_available(void)
{ {
#ifdef CONFIG_KVM #ifdef CONFIG_KVM

View File

@ -753,9 +753,6 @@ int main(int argc, char **argv)
} }
cpu_model = NULL; cpu_model = NULL;
#if defined(cpudef_setup)
cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
#endif
optind = 1; optind = 1;
for(;;) { for(;;) {

View File

@ -582,6 +582,7 @@ DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4,
#define PC_COMPAT_1_3 \ #define PC_COMPAT_1_3 \
PC_CPU_MODEL_IDS("1.3.0") \
{\ {\
.driver = "usb-tablet",\ .driver = "usb-tablet",\
.property = "usb_version",\ .property = "usb_version",\
@ -613,6 +614,7 @@ DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3,
#define PC_COMPAT_1_2 \ #define PC_COMPAT_1_2 \
PC_CPU_MODEL_IDS("1.2.0") \
{\ {\
.driver = "nec-usb-xhci",\ .driver = "nec-usb-xhci",\
.property = "msi",\ .property = "msi",\
@ -651,6 +653,7 @@ DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2,
#define PC_COMPAT_1_1 \ #define PC_COMPAT_1_1 \
PC_CPU_MODEL_IDS("1.1.0") \
{\ {\
.driver = "virtio-scsi-pci",\ .driver = "virtio-scsi-pci",\
.property = "hotplug",\ .property = "hotplug",\
@ -693,6 +696,7 @@ DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2,
#define PC_COMPAT_1_0 \ #define PC_COMPAT_1_0 \
PC_CPU_MODEL_IDS("1.0") \
{\ {\
.driver = TYPE_ISA_FDC,\ .driver = TYPE_ISA_FDC,\
.property = "check_media_rate",\ .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); 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) static void pc_i440fx_0_15_machine_options(MachineClass *m)
{ {
pc_i440fx_1_0_machine_options(m); pc_i440fx_1_0_machine_options(m);
m->hw_version = "0.15"; 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, 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 \ #define PC_COMPAT_0_14 \
PC_CPU_MODEL_IDS("0.14") \
{\ {\
.driver = "virtio-blk-pci",\ .driver = "virtio-blk-pci",\
.property = "event_idx",\ .property = "event_idx",\
@ -771,6 +780,7 @@ DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2,
#define PC_COMPAT_0_13 \ #define PC_COMPAT_0_13 \
PC_CPU_MODEL_IDS("0.13") \
{\ {\
.driver = TYPE_PCI_DEVICE,\ .driver = TYPE_PCI_DEVICE,\
.property = "command_serr_enable",\ .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 \ #define PC_COMPAT_0_12 \
PC_CPU_MODEL_IDS("0.12") \
{\ {\
.driver = "virtio-serial-pci",\ .driver = "virtio-serial-pci",\
.property = "max_ports",\ .property = "max_ports",\
@ -841,6 +852,7 @@ DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13,
#define PC_COMPAT_0_11 \ #define PC_COMPAT_0_11 \
PC_CPU_MODEL_IDS("0.11") \
{\ {\
.driver = "virtio-blk-pci",\ .driver = "virtio-blk-pci",\
.property = "vectors",\ .property = "vectors",\
@ -871,6 +883,7 @@ DEFINE_I440FX_MACHINE(v0_11, "pc-0.11", pc_compat_0_13,
#define PC_COMPAT_0_10 \ #define PC_COMPAT_0_10 \
PC_CPU_MODEL_IDS("0.10") \
{\ {\
.driver = "virtio-blk-pci",\ .driver = "virtio-blk-pci",\
.property = "class",\ .property = "class",\

View File

@ -359,8 +359,29 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_COMPAT_2_5 \ #define PC_COMPAT_2_5 \
HW_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 \ #define PC_COMPAT_2_4 \
HW_COMPAT_2_4 \ HW_COMPAT_2_4 \
PC_CPU_MODEL_IDS("2.4.0") \
{\ {\
.driver = "Haswell-" TYPE_X86_CPU,\ .driver = "Haswell-" TYPE_X86_CPU,\
.property = "abm",\ .property = "abm",\
@ -431,6 +452,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_COMPAT_2_3 \ #define PC_COMPAT_2_3 \
HW_COMPAT_2_3 \ HW_COMPAT_2_3 \
PC_CPU_MODEL_IDS("2.3.0") \
{\ {\
.driver = TYPE_X86_CPU,\ .driver = TYPE_X86_CPU,\
.property = "arat",\ .property = "arat",\
@ -511,6 +533,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_COMPAT_2_2 \ #define PC_COMPAT_2_2 \
HW_COMPAT_2_2 \ HW_COMPAT_2_2 \
PC_CPU_MODEL_IDS("2.3.0") \
{\ {\
.driver = "kvm64" "-" TYPE_X86_CPU,\ .driver = "kvm64" "-" TYPE_X86_CPU,\
.property = "vme",\ .property = "vme",\
@ -604,6 +627,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
#define PC_COMPAT_2_1 \ #define PC_COMPAT_2_1 \
HW_COMPAT_2_1 \ HW_COMPAT_2_1 \
PC_CPU_MODEL_IDS("2.1.0") \
{\ {\
.driver = "coreduo" "-" TYPE_X86_CPU,\ .driver = "coreduo" "-" TYPE_X86_CPU,\
.property = "vmx",\ .property = "vmx",\
@ -616,6 +640,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
}, },
#define PC_COMPAT_2_0 \ #define PC_COMPAT_2_0 \
PC_CPU_MODEL_IDS("2.0.0") \
{\ {\
.driver = "virtio-scsi-pci",\ .driver = "virtio-scsi-pci",\
.property = "any_layout",\ .property = "any_layout",\
@ -675,6 +700,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
}, },
#define PC_COMPAT_1_7 \ #define PC_COMPAT_1_7 \
PC_CPU_MODEL_IDS("1.7.0") \
{\ {\
.driver = TYPE_USB_DEVICE,\ .driver = TYPE_USB_DEVICE,\
.property = "msos-desc",\ .property = "msos-desc",\
@ -692,6 +718,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
}, },
#define PC_COMPAT_1_6 \ #define PC_COMPAT_1_6 \
PC_CPU_MODEL_IDS("1.6.0") \
{\ {\
.driver = "e1000",\ .driver = "e1000",\
.property = "mitigation",\ .property = "mitigation",\
@ -715,6 +742,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
}, },
#define PC_COMPAT_1_5 \ #define PC_COMPAT_1_5 \
PC_CPU_MODEL_IDS("1.5.0") \
{\ {\
.driver = "Conroe-" TYPE_X86_CPU,\ .driver = "Conroe-" TYPE_X86_CPU,\
.property = "model",\ .property = "model",\
@ -758,6 +786,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
}, },
#define PC_COMPAT_1_4 \ #define PC_COMPAT_1_4 \
PC_CPU_MODEL_IDS("1.4.0") \
{\ {\
.driver = "scsi-hd",\ .driver = "scsi-hd",\
.property = "discard_granularity",\ .property = "discard_granularity",\

View File

@ -327,6 +327,15 @@ static inline void qemu_timersub(const struct timeval *val1,
void qemu_set_cloexec(int fd); 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 "hardware version" setting. Used to replace code that exposed
* QEMU_VERSION to guests in the past and need to keep compatibility. * QEMU_VERSION to guests in the past and need to keep compatibility.
* Do not use qemu_hw_version() in new code. * Do not use qemu_hw_version() in new code.

View File

@ -30,7 +30,6 @@ extern const uint32_t arch_type;
void select_soundhw(const char *optarg); void select_soundhw(const char *optarg);
void do_acpitable_option(const QemuOpts *opts); void do_acpitable_option(const QemuOpts *opts);
void do_smbios_option(QemuOpts *opts); void do_smbios_option(QemuOpts *opts);
void cpudef_init(void);
void audio_init(void); void audio_init(void);
int kvm_available(void); int kvm_available(void);
int xen_available(void); int xen_available(void);

View File

@ -4154,9 +4154,6 @@ int main(int argc, char **argv, char **envp)
} }
cpu_model = NULL; cpu_model = NULL;
#if defined(cpudef_setup)
cpudef_setup(); /* parse cpu definitions in target config file (TBD) */
#endif
srand(time(NULL)); srand(time(NULL));

View File

@ -474,25 +474,32 @@ static const X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
const ExtSaveArea x86_ext_save_areas[] = { const ExtSaveArea x86_ext_save_areas[] = {
[XSTATE_YMM_BIT] = [XSTATE_YMM_BIT] =
{ .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX, { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
.offset = 0x240, .size = 0x100 }, .offset = offsetof(X86XSaveArea, avx_state),
.size = sizeof(XSaveAVX) },
[XSTATE_BNDREGS_BIT] = [XSTATE_BNDREGS_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, { .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] = [XSTATE_BNDCSR_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, { .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] = [XSTATE_OPMASK_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, { .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] = [XSTATE_ZMM_Hi256_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, { .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] = [XSTATE_Hi16_ZMM_BIT] =
{ .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, { .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] = [XSTATE_PKRU_BIT] =
{ .feature = FEAT_7_0_ECX, .bits = CPUID_7_0_ECX_PKU, { .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) const char *get_register_name_32(unsigned int reg)
@ -703,6 +710,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_8000_0001_ECX] = .features[FEAT_8000_0001_ECX] =
CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM, CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM,
.xlevel = 0x8000000A, .xlevel = 0x8000000A,
.model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
}, },
{ {
.name = "phenom", .name = "phenom",
@ -799,6 +807,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_1_ECX] = .features[FEAT_1_ECX] =
CPUID_EXT_SSE3, CPUID_EXT_SSE3,
.xlevel = 0x80000004, .xlevel = 0x80000004,
.model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
}, },
{ {
.name = "kvm32", .name = "kvm32",
@ -895,6 +904,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
.features[FEAT_8000_0001_EDX] = .features[FEAT_8000_0001_EDX] =
CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
.xlevel = 0x80000008, .xlevel = 0x80000008,
.model_id = "QEMU Virtual CPU version " QEMU_HW_VERSION,
}, },
{ {
.name = "n270", .name = "n270",
@ -2264,30 +2274,6 @@ void cpu_clear_apic_feature(CPUX86State *env)
#endif /* !CONFIG_USER_ONLY */ #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, void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx) 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 #ifndef CONFIG_USER_ONLY
qemu_register_reset(x86_cpu_machine_reset_cb, cpu); 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); X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
FeatureWord w; FeatureWord w;
static int inited;
cs->env_ptr = env; cs->env_ptr = env;
cpu_exec_init(cs, &error_abort);
object_property_add(obj, "family", "int", object_property_add(obj, "family", "int",
x86_cpuid_version_get_family, 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); 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) static int64_t x86_cpu_get_arch_id(CPUState *cs)

View File

@ -830,6 +830,101 @@ typedef struct {
#define NB_OPMASK_REGS 8 #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 { typedef enum TPRAccess {
TPR_ACCESS_READ, TPR_ACCESS_READ,
TPR_ACCESS_WRITE, TPR_ACCESS_WRITE,
@ -1029,6 +1124,8 @@ typedef struct CPUX86State {
TPRAccess tpr_access_type; TPRAccess tpr_access_type;
} CPUX86State; } CPUX86State;
struct kvm_msrs;
/** /**
* X86CPU: * X86CPU:
* @env: #CPUX86State * @env: #CPUX86State
@ -1081,6 +1178,8 @@ struct X86CPU {
struct DeviceState *apic_state; struct DeviceState *apic_state;
struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram; struct MemoryRegion *cpu_as_root, *cpu_as_mem, *smram;
Notifier machine_done; Notifier machine_done;
struct kvm_msrs *kvm_msr_buf;
}; };
static inline X86CPU *x86_env_get_cpu(CPUX86State *env) 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); X86CPU *cpu_x86_create(const char *cpu_model, Error **errp);
int cpu_x86_exec(CPUState *cpu); int cpu_x86_exec(CPUState *cpu);
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf); 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_x86_support_mca_broadcast(CPUX86State *env);
int cpu_get_pic_interrupt(CPUX86State *s); 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_exec cpu_x86_exec
#define cpu_signal_handler cpu_x86_signal_handler #define cpu_signal_handler cpu_x86_signal_handler
#define cpu_list x86_cpu_list #define cpu_list x86_cpu_list
#define cpudef_setup x86_cpudef_setup
/* MMU modes definitions */ /* MMU modes definitions */
#define MMU_MODE0_SUFFIX _ksmap #define MMU_MODE0_SUFFIX _ksmap

View File

@ -57,6 +57,10 @@
#define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_WALL_CLOCK 0x11
#define MSR_KVM_SYSTEM_TIME 0x12 #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 #ifndef BUS_MCEERR_AR
#define BUS_MCEERR_AR 4 #define BUS_MCEERR_AR 4
#endif #endif
@ -914,6 +918,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
if (has_xsave) { if (has_xsave) {
env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_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) { if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
has_msr_mtrr = true; has_msr_mtrr = true;
@ -1307,12 +1312,34 @@ static int kvm_put_fpu(X86CPU *cpu)
#define XSAVE_Hi16_ZMM 416 #define XSAVE_Hi16_ZMM 416
#define XSAVE_PKRU 672 #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) static int kvm_put_xsave(X86CPU *cpu)
{ {
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
struct kvm_xsave* xsave = env->kvm_xsave_buf; X86XSaveArea *xsave = env->kvm_xsave_buf;
uint16_t cwd, swd, twd; uint16_t cwd, swd, twd;
uint8_t *xmm, *ymmh, *zmmh;
int i, r; int i, r;
if (!has_xsave) { if (!has_xsave) {
@ -1327,25 +1354,26 @@ static int kvm_put_xsave(X86CPU *cpu)
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
twd |= (!env->fptags[i]) << i; twd |= (!env->fptags[i]) << i;
} }
xsave->region[XSAVE_FCW_FSW] = (uint32_t)(swd << 16) + cwd; xsave->legacy.fcw = cwd;
xsave->region[XSAVE_FTW_FOP] = (uint32_t)(env->fpop << 16) + twd; xsave->legacy.fsw = swd;
memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip)); xsave->legacy.ftw = twd;
memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp)); xsave->legacy.fpop = env->fpop;
memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs, xsave->legacy.fpip = env->fpip;
xsave->legacy.fpdp = env->fpdp;
memcpy(&xsave->legacy.fpregs, env->fpregs,
sizeof env->fpregs); sizeof env->fpregs);
xsave->region[XSAVE_MXCSR] = env->mxcsr; xsave->legacy.mxcsr = env->mxcsr;
*(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv; xsave->header.xstate_bv = env->xstate_bv;
memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs, memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs,
sizeof env->bnd_regs); sizeof env->bnd_regs);
memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs, xsave->bndcsr_state.bndcsr = env->bndcs_regs;
sizeof(env->bndcs_regs)); memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs,
memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs,
sizeof env->opmask_regs); sizeof env->opmask_regs);
xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; for (i = 0; i < CPU_NB_REGS; i++) {
ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; uint8_t *xmm = xsave->legacy.xmm_regs[i];
zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; uint8_t *ymmh = xsave->avx_state.ymmh[i];
for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { uint8_t *zmmh = xsave->zmm_hi256_state.zmm_hi256[i];
stq_p(xmm, env->xmm_regs[i].ZMM_Q(0)); stq_p(xmm, env->xmm_regs[i].ZMM_Q(0));
stq_p(xmm+8, env->xmm_regs[i].ZMM_Q(1)); stq_p(xmm+8, env->xmm_regs[i].ZMM_Q(1));
stq_p(ymmh, env->xmm_regs[i].ZMM_Q(2)); 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 #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]); 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 #endif
r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave); r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
return r; return r;
@ -1431,35 +1459,38 @@ static int kvm_put_sregs(X86CPU *cpu)
return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs); return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs);
} }
static void kvm_msr_entry_set(struct kvm_msr_entry *entry, static void kvm_msr_buf_reset(X86CPU *cpu)
uint32_t index, uint64_t value)
{ {
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->index = index;
entry->reserved = 0; entry->reserved = 0;
entry->data = value; entry->data = value;
msrs->nmsrs++;
} }
static int kvm_put_tscdeadline_msr(X86CPU *cpu) static int kvm_put_tscdeadline_msr(X86CPU *cpu)
{ {
CPUX86State *env = &cpu->env; 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; int ret;
if (!has_msr_tsc_deadline) { if (!has_msr_tsc_deadline) {
return 0; return 0;
} }
kvm_msr_entry_set(&msrs[0], MSR_IA32_TSCDEADLINE, env->tsc_deadline); kvm_msr_buf_reset(cpu);
kvm_msr_entry_add(cpu, MSR_IA32_TSCDEADLINE, env->tsc_deadline);
msr_data.info = (struct kvm_msrs) { ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
.nmsrs = 1,
};
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1476,24 +1507,17 @@ static int kvm_put_tscdeadline_msr(X86CPU *cpu)
*/ */
static int kvm_put_msr_feature_control(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; int ret;
if (!has_msr_feature_control) { if (!has_msr_feature_control) {
return 0; 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); cpu->env.msr_ia32_feature_control);
msr_data.info = (struct kvm_msrs) { ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
.nmsrs = 1,
};
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1505,49 +1529,46 @@ static int kvm_put_msr_feature_control(X86CPU *cpu)
static int kvm_put_msrs(X86CPU *cpu, int level) static int kvm_put_msrs(X86CPU *cpu, int level)
{ {
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
struct { int i;
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 ret; int ret;
kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs); kvm_msr_buf_reset(cpu);
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_add(cpu, MSR_IA32_SYSENTER_CS, env->sysenter_cs);
kvm_msr_entry_set(&msrs[n++], MSR_PAT, env->pat); 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) { 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) { 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) { 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) { 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) { 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); env->msr_ia32_misc_enable);
} }
if (has_msr_smbase) { 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) { 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) { 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 #ifdef TARGET_X86_64
if (lm_capable_kernel) { if (lm_capable_kernel) {
kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar); kvm_msr_entry_add(cpu, MSR_CSTAR, env->cstar);
kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase); kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase);
kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask); kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask);
kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar); kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar);
} }
#endif #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. * for normal writeback. Limit them to reset or full state updates.
*/ */
if (level >= KVM_PUT_RESET_STATE) { if (level >= KVM_PUT_RESET_STATE) {
kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc); kvm_msr_entry_add(cpu, MSR_IA32_TSC, env->tsc);
kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, env->system_time_msr);
env->system_time_msr); kvm_msr_entry_add(cpu, MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
if (has_msr_async_pf_en) { if (has_msr_async_pf_en) {
kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN, kvm_msr_entry_add(cpu, MSR_KVM_ASYNC_PF_EN, env->async_pf_en_msr);
env->async_pf_en_msr);
} }
if (has_msr_pv_eoi_en) { if (has_msr_pv_eoi_en) {
kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN, kvm_msr_entry_add(cpu, MSR_KVM_PV_EOI_EN, env->pv_eoi_en_msr);
env->pv_eoi_en_msr);
} }
if (has_msr_kvm_steal_time) { if (has_msr_kvm_steal_time) {
kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME, kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr);
env->steal_time_msr);
} }
if (has_msr_architectural_pmu) { if (has_msr_architectural_pmu) {
/* Stop the counter. */ /* Stop the counter. */
kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL, 0); kvm_msr_entry_add(cpu, 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_GLOBAL_CTRL, 0);
/* Set the counter values. */ /* Set the counter values. */
for (i = 0; i < MAX_FIXED_COUNTERS; i++) { 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]); env->msr_fixed_counters[i]);
} }
for (i = 0; i < num_architectural_pmu_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]); 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]); 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); 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); env->msr_global_ovf_ctrl);
/* Now start the PMU. */ /* 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); 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); env->msr_global_ctrl);
} }
if (has_msr_hv_hypercall) { 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); 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); env->msr_hv_hypercall);
} }
if (has_msr_hv_vapic) { 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); env->msr_hv_vapic);
} }
if (has_msr_hv_tsc) { if (has_msr_hv_tsc) {
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC, kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, env->msr_hv_tsc);
env->msr_hv_tsc);
} }
if (has_msr_hv_crash) { if (has_msr_hv_crash) {
int j; int j;
for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; 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]); 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); HV_X64_MSR_CRASH_CTL_NOTIFY);
} }
if (has_msr_hv_runtime) { if (has_msr_hv_runtime) {
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_VP_RUNTIME, kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, env->msr_hv_runtime);
env->msr_hv_runtime);
} }
if (cpu->hyperv_synic) { if (cpu->hyperv_synic) {
int j; 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); 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); 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); 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); env->msr_hv_synic_msg_page);
for (j = 0; j < ARRAY_SIZE(env->msr_hv_synic_sint); j++) { 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]); env->msr_hv_synic_sint[j]);
} }
} }
@ -1647,44 +1662,33 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
int j; int j;
for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_config); 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]); env->msr_hv_stimer_config[j]);
} }
for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_count); 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]); env->msr_hv_stimer_count[j]);
} }
} }
if (has_msr_mtrr) { if (has_msr_mtrr) {
kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype); kvm_msr_entry_add(cpu, MSR_MTRRdefType, env->mtrr_deftype);
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, env->mtrr_fixed[0]);
MSR_MTRRfix64K_00000, env->mtrr_fixed[0]); kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, env->mtrr_fixed[1]);
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]);
MSR_MTRRfix16K_80000, env->mtrr_fixed[1]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]);
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]);
MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]);
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]);
MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]);
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]);
MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]);
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]);
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]);
for (i = 0; i < MSR_MTRRcap_VCNT; i++) { for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i),
MSR_MTRRphysBase(i), env->mtrr_var[i].base); env->mtrr_var[i].base);
kvm_msr_entry_set(&msrs[n++], kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i),
MSR_MTRRphysMask(i), env->mtrr_var[i].mask); env->mtrr_var[i].mask);
} }
} }
@ -1694,23 +1698,19 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
if (env->mcg_cap) { if (env->mcg_cap) {
int i; int i;
kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status); kvm_msr_entry_add(cpu, 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_CTL, env->mcg_ctl);
for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) { 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) { ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf);
.nmsrs = n,
};
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
assert(ret == n); assert(ret == cpu->kvm_msr_buf->nmsrs);
return 0; return 0;
} }
@ -1748,9 +1748,8 @@ static int kvm_get_fpu(X86CPU *cpu)
static int kvm_get_xsave(X86CPU *cpu) static int kvm_get_xsave(X86CPU *cpu)
{ {
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
struct kvm_xsave* xsave = env->kvm_xsave_buf; X86XSaveArea *xsave = env->kvm_xsave_buf;
int ret, i; int ret, i;
const uint8_t *xmm, *ymmh, *zmmh;
uint16_t cwd, swd, twd; uint16_t cwd, swd, twd;
if (!has_xsave) { if (!has_xsave) {
@ -1762,33 +1761,32 @@ static int kvm_get_xsave(X86CPU *cpu)
return ret; return ret;
} }
cwd = (uint16_t)xsave->region[XSAVE_FCW_FSW]; cwd = xsave->legacy.fcw;
swd = (uint16_t)(xsave->region[XSAVE_FCW_FSW] >> 16); swd = xsave->legacy.fsw;
twd = (uint16_t)xsave->region[XSAVE_FTW_FOP]; twd = xsave->legacy.ftw;
env->fpop = (uint16_t)(xsave->region[XSAVE_FTW_FOP] >> 16); env->fpop = xsave->legacy.fpop;
env->fpstt = (swd >> 11) & 7; env->fpstt = (swd >> 11) & 7;
env->fpus = swd; env->fpus = swd;
env->fpuc = cwd; env->fpuc = cwd;
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
env->fptags[i] = !((twd >> i) & 1); env->fptags[i] = !((twd >> i) & 1);
} }
memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip)); env->fpip = xsave->legacy.fpip;
memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp)); env->fpdp = xsave->legacy.fpdp;
env->mxcsr = xsave->region[XSAVE_MXCSR]; env->mxcsr = xsave->legacy.mxcsr;
memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE], memcpy(env->fpregs, &xsave->legacy.fpregs,
sizeof env->fpregs); sizeof env->fpregs);
env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; env->xstate_bv = xsave->header.xstate_bv;
memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS], memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs,
sizeof env->bnd_regs); sizeof env->bnd_regs);
memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR], env->bndcs_regs = xsave->bndcsr_state.bndcsr;
sizeof(env->bndcs_regs)); memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs,
memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK],
sizeof env->opmask_regs); sizeof env->opmask_regs);
xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; for (i = 0; i < CPU_NB_REGS; i++) {
ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; uint8_t *xmm = xsave->legacy.xmm_regs[i];
zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; uint8_t *ymmh = xsave->avx_state.ymmh[i];
for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { 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(0) = ldq_p(xmm);
env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm+8); env->xmm_regs[i].ZMM_Q(1) = ldq_p(xmm+8);
env->xmm_regs[i].ZMM_Q(2) = ldq_p(ymmh); 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 #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]); 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 #endif
return 0; return 0;
} }
@ -1923,125 +1921,122 @@ static int kvm_get_sregs(X86CPU *cpu)
static int kvm_get_msrs(X86CPU *cpu) static int kvm_get_msrs(X86CPU *cpu)
{ {
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
struct { struct kvm_msr_entry *msrs = cpu->kvm_msr_buf->entries;
struct kvm_msrs info; int ret, i;
struct kvm_msr_entry entries[150];
} msr_data;
struct kvm_msr_entry *msrs = msr_data.entries;
int ret, i, n;
n = 0; kvm_msr_buf_reset(cpu);
msrs[n++].index = MSR_IA32_SYSENTER_CS;
msrs[n++].index = MSR_IA32_SYSENTER_ESP; kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_CS, 0);
msrs[n++].index = MSR_IA32_SYSENTER_EIP; kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_ESP, 0);
msrs[n++].index = MSR_PAT; kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_EIP, 0);
kvm_msr_entry_add(cpu, MSR_PAT, 0);
if (has_msr_star) { if (has_msr_star) {
msrs[n++].index = MSR_STAR; kvm_msr_entry_add(cpu, MSR_STAR, 0);
} }
if (has_msr_hsave_pa) { 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) { 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) { 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) { 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) { 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) { if (has_msr_smbase) {
msrs[n++].index = MSR_IA32_SMBASE; kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, 0);
} }
if (has_msr_feature_control) { 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) { if (has_msr_bndcfgs) {
msrs[n++].index = MSR_IA32_BNDCFGS; kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, 0);
} }
if (has_msr_xss) { if (has_msr_xss) {
msrs[n++].index = MSR_IA32_XSS; kvm_msr_entry_add(cpu, MSR_IA32_XSS, 0);
} }
if (!env->tsc_valid) { 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(); env->tsc_valid = !runstate_is_running();
} }
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
if (lm_capable_kernel) { if (lm_capable_kernel) {
msrs[n++].index = MSR_CSTAR; kvm_msr_entry_add(cpu, MSR_CSTAR, 0);
msrs[n++].index = MSR_KERNELGSBASE; kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, 0);
msrs[n++].index = MSR_FMASK; kvm_msr_entry_add(cpu, MSR_FMASK, 0);
msrs[n++].index = MSR_LSTAR; kvm_msr_entry_add(cpu, MSR_LSTAR, 0);
} }
#endif #endif
msrs[n++].index = MSR_KVM_SYSTEM_TIME; kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, 0);
msrs[n++].index = MSR_KVM_WALL_CLOCK; kvm_msr_entry_add(cpu, MSR_KVM_WALL_CLOCK, 0);
if (has_msr_async_pf_en) { 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) { 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) { 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) { if (has_msr_architectural_pmu) {
msrs[n++].index = MSR_CORE_PERF_FIXED_CTR_CTRL; kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
msrs[n++].index = MSR_CORE_PERF_GLOBAL_CTRL; kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0);
msrs[n++].index = MSR_CORE_PERF_GLOBAL_STATUS; kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, 0);
msrs[n++].index = MSR_CORE_PERF_GLOBAL_OVF_CTRL; kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, 0);
for (i = 0; i < MAX_FIXED_COUNTERS; i++) { 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++) { for (i = 0; i < num_architectural_pmu_counters; i++) {
msrs[n++].index = MSR_P6_PERFCTR0 + i; kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i, 0);
msrs[n++].index = MSR_P6_EVNTSEL0 + i; kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i, 0);
} }
} }
if (env->mcg_cap) { if (env->mcg_cap) {
msrs[n++].index = MSR_MCG_STATUS; kvm_msr_entry_add(cpu, MSR_MCG_STATUS, 0);
msrs[n++].index = MSR_MCG_CTL; kvm_msr_entry_add(cpu, MSR_MCG_CTL, 0);
for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) { 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) { if (has_msr_hv_hypercall) {
msrs[n++].index = HV_X64_MSR_HYPERCALL; kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL, 0);
msrs[n++].index = HV_X64_MSR_GUEST_OS_ID; kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID, 0);
} }
if (has_msr_hv_vapic) { 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) { 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) { if (has_msr_hv_crash) {
int j; int j;
for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; 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) { 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) { if (cpu->hyperv_synic) {
uint32_t msr; uint32_t msr;
msrs[n++].index = HV_X64_MSR_SCONTROL; kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL, 0);
msrs[n++].index = HV_X64_MSR_SVERSION; kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION, 0);
msrs[n++].index = HV_X64_MSR_SIEFP; kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP, 0);
msrs[n++].index = HV_X64_MSR_SIMP; kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP, 0);
for (msr = HV_X64_MSR_SINT0; msr <= HV_X64_MSR_SINT15; msr++) { 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) { 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; for (msr = HV_X64_MSR_STIMER0_CONFIG; msr <= HV_X64_MSR_STIMER3_COUNT;
msr++) { msr++) {
msrs[n++].index = msr; kvm_msr_entry_add(cpu, msr, 0);
} }
} }
if (has_msr_mtrr) { if (has_msr_mtrr) {
msrs[n++].index = MSR_MTRRdefType; kvm_msr_entry_add(cpu, MSR_MTRRdefType, 0);
msrs[n++].index = MSR_MTRRfix64K_00000; kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, 0);
msrs[n++].index = MSR_MTRRfix16K_80000; kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, 0);
msrs[n++].index = MSR_MTRRfix16K_A0000; kvm_msr_entry_add(cpu, MSR_MTRRfix16K_A0000, 0);
msrs[n++].index = MSR_MTRRfix4K_C0000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C0000, 0);
msrs[n++].index = MSR_MTRRfix4K_C8000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C8000, 0);
msrs[n++].index = MSR_MTRRfix4K_D0000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D0000, 0);
msrs[n++].index = MSR_MTRRfix4K_D8000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D8000, 0);
msrs[n++].index = MSR_MTRRfix4K_E0000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E0000, 0);
msrs[n++].index = MSR_MTRRfix4K_E8000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E8000, 0);
msrs[n++].index = MSR_MTRRfix4K_F0000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, 0);
msrs[n++].index = MSR_MTRRfix4K_F8000; kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, 0);
for (i = 0; i < MSR_MTRRcap_VCNT; i++) { for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
msrs[n++].index = MSR_MTRRphysBase(i); kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i), 0);
msrs[n++].index = MSR_MTRRphysMask(i); kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), 0);
} }
} }
msr_data.info = (struct kvm_msrs) { ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, cpu->kvm_msr_buf);
.nmsrs = n,
};
ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
assert(ret == n); assert(ret == cpu->kvm_msr_buf->nmsrs);
for (i = 0; i < ret; i++) { for (i = 0; i < ret; i++) {
uint32_t index = msrs[i].index; uint32_t index = msrs[i].index;
switch (index) { switch (index) {

View File

@ -8144,6 +8144,12 @@ void tcg_x86_init(void)
"bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub" "bnd0_ub", "bnd1_ub", "bnd2_ub", "bnd3_ub"
}; };
int i; int i;
static bool initialized;
if (initialized) {
return;
}
initialized = true;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
cpu_cc_op = tcg_global_mem_new_i32(cpu_env, cpu_cc_op = tcg_global_mem_new_i32(cpu_env,

View File

@ -44,14 +44,7 @@ extern int madvise(caddr_t, size_t, int);
static bool fips_enabled = false; static bool fips_enabled = false;
/* Starting on QEMU 2.5, qemu_hw_version() returns "2.5+" by default static const char *hw_version = QEMU_HW_VERSION;
* 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+";
int socket_set_cork(int fd, int v) int socket_set_cork(int fd, int v)
{ {

7
vl.c
View File

@ -4047,13 +4047,6 @@ int main(int argc, char **argv, char **envp)
qemu_set_hw_version(machine_class->hw_version); 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)) { if (cpu_model && is_help_option(cpu_model)) {
list_cpus(stdout, &fprintf, cpu_model); list_cpus(stdout, &fprintf, cpu_model);
exit(0); exit(0);