summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/i386/cpu.c15
-rw-r--r--target/i386/cpu.h7
-rw-r--r--target/i386/kvm/kvm.c26
3 files changed, 33 insertions, 15 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 8154343cc4..d1d057fabe 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6258,10 +6258,6 @@ static void x86_cpu_hyperv_realize(X86CPU *cpu)
cpu->hyperv_interface_id[2] = 0;
cpu->hyperv_interface_id[3] = 0;
- /* Hypervisor system identity */
- cpu->hyperv_version_id[0] = 0x00001bbc;
- cpu->hyperv_version_id[1] = 0x00060001;
-
/* Hypervisor implementation limits */
cpu->hyperv_limits[0] = 64;
cpu->hyperv_limits[1] = 0;
@@ -6840,6 +6836,17 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("hv-passthrough", X86CPU, hyperv_passthrough, false),
DEFINE_PROP_BOOL("hv-enforce-cpuid", X86CPU, hyperv_enforce_cpuid, false),
+ /* WS2008R2 identify by default */
+ DEFINE_PROP_UINT32("hv-version-id-build", X86CPU, hyperv_ver_id_build,
+ 0x1bbc),
+ DEFINE_PROP_UINT16("hv-version-id-major", X86CPU, hyperv_ver_id_major,
+ 0x0006),
+ DEFINE_PROP_UINT16("hv-version-id-minor", X86CPU, hyperv_ver_id_minor,
+ 0x0001),
+ DEFINE_PROP_UINT32("hv-version-id-spack", X86CPU, hyperv_ver_id_sp, 0),
+ DEFINE_PROP_UINT8("hv-version-id-sbranch", X86CPU, hyperv_ver_id_sb, 0),
+ DEFINE_PROP_UINT32("hv-version-id-snumber", X86CPU, hyperv_ver_id_sn, 0),
+
DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, true),
DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
DEFINE_PROP_BOOL("x-force-features", X86CPU, force_features, false),
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 65f0ee2caf..3edaad7688 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1717,10 +1717,15 @@ struct X86CPU {
OnOffAuto hyperv_no_nonarch_cs;
uint32_t hyperv_vendor_id[3];
uint32_t hyperv_interface_id[4];
- uint32_t hyperv_version_id[4];
uint32_t hyperv_limits[3];
uint32_t hyperv_nested[4];
bool hyperv_enforce_cpuid;
+ uint32_t hyperv_ver_id_build;
+ uint16_t hyperv_ver_id_major;
+ uint16_t hyperv_ver_id_minor;
+ uint32_t hyperv_ver_id_sp;
+ uint8_t hyperv_ver_id_sb;
+ uint32_t hyperv_ver_id_sn;
bool check_cpuid;
bool enforce_cpuid;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 68faf72e34..f25837f63f 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1258,14 +1258,18 @@ bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp)
cpu->hyperv_interface_id[3] =
hv_cpuid_get_host(cs, HV_CPUID_INTERFACE, R_EDX);
- cpu->hyperv_version_id[0] =
+ cpu->hyperv_ver_id_build =
hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_EAX);
- cpu->hyperv_version_id[1] =
- hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_EBX);
- cpu->hyperv_version_id[2] =
+ cpu->hyperv_ver_id_major =
+ hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_EBX) >> 16;
+ cpu->hyperv_ver_id_minor =
+ hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_EBX) & 0xffff;
+ cpu->hyperv_ver_id_sp =
hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_ECX);
- cpu->hyperv_version_id[3] =
- hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_EDX);
+ cpu->hyperv_ver_id_sb =
+ hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_EDX) >> 24;
+ cpu->hyperv_ver_id_sn =
+ hv_cpuid_get_host(cs, HV_CPUID_VERSION, R_EDX) & 0xffffff;
cpu->hv_max_vps = hv_cpuid_get_host(cs, HV_CPUID_IMPLEMENT_LIMITS,
R_EAX);
@@ -1351,10 +1355,12 @@ static int hyperv_fill_cpuids(CPUState *cs,
c = &cpuid_ent[cpuid_i++];
c->function = HV_CPUID_VERSION;
- c->eax = cpu->hyperv_version_id[0];
- c->ebx = cpu->hyperv_version_id[1];
- c->ecx = cpu->hyperv_version_id[2];
- c->edx = cpu->hyperv_version_id[3];
+ c->eax = cpu->hyperv_ver_id_build;
+ c->ebx = (uint32_t)cpu->hyperv_ver_id_major << 16 |
+ cpu->hyperv_ver_id_minor;
+ c->ecx = cpu->hyperv_ver_id_sp;
+ c->edx = (uint32_t)cpu->hyperv_ver_id_sb << 24 |
+ (cpu->hyperv_ver_id_sn & 0xffffff);
c = &cpuid_ent[cpuid_i++];
c->function = HV_CPUID_FEATURES;