of host setup. To keep guests secure, this can only be used in conjunction with
exposing correct vCPU topology and vCPU pinning.
+3.20. hv-version-id-{build,major,minor,spack,sbranch,snumber}
+=============================================================
+This changes Hyper-V version identification in CPUID 0x40000002.EAX-EDX from the
+default (WS2008R2).
+- hv-version-id-build sets 'Build Number' (32 bits)
+- hv-version-id-major sets 'Major Version' (16 bits)
+- hv-version-id-minor sets 'Minor Version' (16 bits)
+- hv-version-id-spack sets 'Service Pack' (32 bits)
+- hv-version-id-sbranch sets 'Service Branch' (8 bits)
+- hv-version-id-snumber sets 'Service Number' (24 bits)
+
+Note: hv-version-id-* are not enlightenments and thus don't enable Hyper-V
+identification when specified without any other enlightenments.
+
4. Supplementary features
=========================
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;
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),
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;
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);
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;