@samitouri / QOSamiQemu / commits / 68438cb3cb

whpx: i386: workaround for Windows 10 support

Windows Server 2022 and later support WHvCapabilityCodeProcessorPerfmonFeatures and WHvPartitionPropertyCodeSyntheticProcessorFeaturesBanks. Windows 10 supports neither of those. As the QEMU executable doesn't have a manifest, OS version queries do not return the actual Windows version but 6.2.9200 which corresponds to Windows 8. Windows Server 2022 and Windows 11 still use the 10.0 number, with distinction being the build number. As such, use the absence of perf monitoring feature query as a cutoff to detect if a legacy OS is present. Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr> Link: https://lore.kernel.org/r/20260324151323.74473-2-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Mohamed Mediouni committed Mar 24, 2026 at 16:13 UTC 68438cb3cbcb298af63383a7d537e6610daf96a3
1 file changed +28 -15
target/i386/whpx/whpx-all.c
+28 -15
@@ -1948,6 +1948,7 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
1948 WHV_CAPABILITY_FEATURES features = {0};
1949 WHV_PROCESSOR_FEATURES_BANKS processor_features;
1950 WHV_PROCESSOR_PERFMON_FEATURES perfmon_features;
1951 + bool is_legacy_os = false;
1952
1953 whpx = &whpx_global;
1954
@@ -2096,21 +2097,29 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
2097 hr = whp_dispatch.WHvGetCapability(
2098 WHvCapabilityCodeProcessorPerfmonFeatures, &perfmon_features,
2099 sizeof(WHV_PROCESSOR_PERFMON_FEATURES), &whpx_cap_size);
2100 + /*
2101 + * Relying on this is a crutch to maintain Windows 10 support.
2102 + *
2103 + * WHvCapabilityCodeProcessorPerfmonFeatures and
2104 + * WHvPartitionPropertyCodeSyntheticProcessorFeaturesBanks
2105 + * are implemented starting from Windows Server 2022 (build 20348).
2106 + */
2107 if (FAILED(hr)) {
2100 - error_report("WHPX: Failed to get performance monitoring features, hr=%08lx", hr);
2101 - ret = -ENOSPC;
2102 - goto error;
2103 - }
2104 -
2105 - hr = whp_dispatch.WHvSetPartitionProperty(
2106 - whpx->partition,
2107 - WHvPartitionPropertyCodeProcessorPerfmonFeatures,
2108 - &perfmon_features,
2109 - sizeof(WHV_PROCESSOR_PERFMON_FEATURES));
2110 - if (FAILED(hr)) {
2111 - error_report("WHPX: Failed to set performance monitoring features, hr=%08lx", hr);
2112 - ret = -EINVAL;
2113 - goto error;
2108 + warn_report("WHPX: Failed to get performance "
2109 + "monitoring features, hr=%08lx", hr);
2110 + is_legacy_os = true;
2111 + } else {
2112 + hr = whp_dispatch.WHvSetPartitionProperty(
2113 + whpx->partition,
2114 + WHvPartitionPropertyCodeProcessorPerfmonFeatures,
2115 + &perfmon_features,
2116 + sizeof(WHV_PROCESSOR_PERFMON_FEATURES));
2117 + if (FAILED(hr)) {
2118 + error_report("WHPX: Failed to set performance "
2119 + "monitoring features, hr=%08lx", hr);
2120 + ret = -EINVAL;
2121 + goto error;
2122 + }
2123 }
2124
2125 /* Enable synthetic processor features */
@@ -2138,7 +2147,7 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
2147 synthetic_features.Bank0.DirectSyntheticTimers = 1;
2148 }
2149
2141 - if (whpx->hyperv_enlightenments_allowed) {
2150 + if (!is_legacy_os && whpx->hyperv_enlightenments_allowed) {
2151 hr = whp_dispatch.WHvSetPartitionProperty(
2152 whpx->partition,
2153 WHvPartitionPropertyCodeSyntheticProcessorFeaturesBanks,
@@ -2149,6 +2158,10 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
2158 ret = -EINVAL;
2159 goto error;
2160 }
2161 + } else if (is_legacy_os && whpx->hyperv_enlightenments_required) {
2162 + error_report("Hyper-V enlightenments not available on legacy Windows");
2163 + ret = -EINVAL;
2164 + goto error;
2165 }
2166
2167 /* Register for MSR and CPUID exits */