From: Akshey Taneja <[email protected]>
WHvCapabilityCodeProcessorFeaturesBanks and the matching partition
property are implemented starting from Windows 10 version 20H1.
On earlier Windows 10 releases, the capability query returns
WHV_E_UNKNOWN_CAPABILITY (0x80370300) and whpx_accel_init()
aborts with -ENOSPC, reported to the user as "failed to initialize
whpx: No space left on device". This regressed older Windows 10
releases in 8b87283ce4 ("whpx: i386: enable all supported host features").
Fall back to the original single-bank WHvCapabilityCodeProcessorFeatures
on legacy hosts and skip the corresponding SetPartitionProperty, which
restores the pre-8b87283ce4 behaviour there.
Reported-on: Windows 10 Enterprise LTSC 17763, Intel i7-6700
Signed-off-by: Akshey Taneja <[email protected]>
[Editing patch for reflecting the availability of this API, which is
available in Windows 10 version 2004 onwards]
Reviewed-by: Mohamed Mediouni <[email protected]>
Signed-off-by: Mohamed Mediouni <[email protected]>
---
target/i386/whpx/whpx-all.c | 59 +++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 16 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 065cfacf3b..7552e9f4da 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -3331,13 +3331,33 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
memset(&processor_features, 0, sizeof(WHV_PROCESSOR_FEATURES_BANKS));
processor_features.BanksCount = 2;
- hr = whp_dispatch.WHvGetCapability(
- WHvCapabilityCodeProcessorFeaturesBanks, &processor_features,
- sizeof(WHV_PROCESSOR_FEATURES_BANKS), &whpx_cap_size);
- if (FAILED(hr)) {
- error_report("WHPX: Failed to get processor features, hr=%08lx", hr);
- ret = -ENOSPC;
- goto error;
+ if (whpx_is_legacy_os()) {
+ /*
+ * WHvCapabilityCodeProcessorFeaturesBanks is implemented starting
+ * from Windows 10 version 20H2 (19041). Fall back to the single-bank
+ * capability on earlier Windows 10 releases.
+ */
+ WHV_PROCESSOR_FEATURES legacy_features = {0};
+
+ processor_features.BanksCount = 1;
+ hr = whp_dispatch.WHvGetCapability(
+ WHvCapabilityCodeProcessorFeatures, &legacy_features,
+ sizeof(legacy_features), &whpx_cap_size);
+ if (FAILED(hr)) {
+ warn_report("WHPX: Failed to get legacy processor features, "
+ "hr=%08lx", hr);
+ } else {
+ processor_features.Bank0 = legacy_features;
+ }
+ } else {
+ hr = whp_dispatch.WHvGetCapability(
+ WHvCapabilityCodeProcessorFeaturesBanks, &processor_features,
+ sizeof(WHV_PROCESSOR_FEATURES_BANKS), &whpx_cap_size);
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to get processor features, hr=%08lx",
hr);
+ ret = -ENOSPC;
+ goto error;
+ }
}
whpx_rdtsc_cap = processor_features.Bank0.RdtscpSupport;
@@ -3382,15 +3402,22 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
}
}
- hr = whp_dispatch.WHvSetPartitionProperty(
- whpx->partition,
- WHvPartitionPropertyCodeProcessorFeaturesBanks,
- &processor_features,
- sizeof(WHV_PROCESSOR_FEATURES_BANKS));
- if (FAILED(hr)) {
- error_report("WHPX: Failed to set processor features, hr=%08lx", hr);
- ret = -EINVAL;
- goto error;
+ /*
+ * The matching partition property is also Windows Server 2022 and later.
+ * Legacy hosts simply keep the features the hypervisor gave them, which
+ * is how WHPX behaved before the banked feature set was introduced.
+ */
+ if (!whpx_is_legacy_os()) {
+ hr = whp_dispatch.WHvSetPartitionProperty(
+ whpx->partition,
+ WHvPartitionPropertyCodeProcessorFeaturesBanks,
+ &processor_features,
+ sizeof(WHV_PROCESSOR_FEATURES_BANKS));
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to set processor features, hr=%08lx",
hr);
+ ret = -EINVAL;
+ goto error;
+ }
}
--
2.54.0 (Apple Git-157)