On a heterogeneous arm64 system, KVM's PMU emulation is based on the features of a single host PMU instance. When a vCPU is migrated to a pCPU with an incompatible PMU, counters such as PMCCNTR_EL0 stop incrementing.
Although this behavior is permitted by the architecture, Windows does not handle it gracefully and may crash with a division-by-zero error. The current workaround requires VMMs to pin vCPUs to a set of pCPUs that share a compatible PMU. This is difficult to implement correctly in QEMU/libvirt, where pinning occurs after vCPU initialization, and it also restricts the guest to a subset of available pCPUs. This patch introduces the KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY attribute. If set, PMUv3 will be emulated without programmable event counters. KVM will be able to run VCPUs on any physical CPUs with a compatible hardware PMU. This allows Windows guests to run reliably on heterogeneous systems without crashing, even without vCPU pinning, and enables VMMs to schedule vCPUs across all available pCPUs, making full use of the host hardware. A QEMU patch that demonstrates the usage of the new attribute is available at: https://lore.kernel.org/qemu-devel/[email protected]/ ("[PATCH RFC v2] target/arm/kvm: Choose PMU backend") Signed-off-by: Akihiko Odaki <[email protected]> --- Changes in v4: - Extracted kvm_pmu_enabled_counter_mask() into a separate patch. - Added patch "KVM: arm64: PMU: Protect the list of PMUs with RCU". - Merged KVM_REQ_CREATE_PMU into KVM_REQ_RELOAD_PMU. - Added a check to avoid unnecessary KVM_REQ_RELOAD_PMU requests. - Dropped the change to avoid setting kvm_arm_set_default_pmu() when KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY is not set. - Link to v3: https://lore.kernel.org/r/[email protected] Changes in v3: - Renamed the attribute to KVM_ARM_VCPU_PMU_V3_FIXED_COUNTERS_ONLY. - Changed to request the creation of perf counters when loading vCPU. - Link to v2: https://lore.kernel.org/r/[email protected] Changes in v2: - Added the KVM_ARM_VCPU_PMU_V3_COMPOSITION attribute to opt in the feature. - Added code to handle overflow. - Link to v1: https://lore.kernel.org/r/[email protected] --- Akihiko Odaki (4): KVM: arm64: PMU: Add kvm_pmu_enabled_counter_mask() KVM: arm64: PMU: Protect the list of PMUs with RCU KVM: arm64: PMU: Introduce FIXED_COUNTERS_ONLY KVM: arm64: selftests: Test PMU_V3_FIXED_COUNTERS_ONLY Documentation/virt/kvm/devices/vcpu.rst | 29 ++++ arch/arm64/include/asm/kvm_host.h | 2 + arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/pmu-emul.c | 190 ++++++++++++++------- include/kvm/arm_pmu.h | 2 + .../selftests/kvm/arm64/vpmu_counter_access.c | 148 +++++++++++++--- 7 files changed, 290 insertions(+), 83 deletions(-) --- base-commit: ef87500dc466ef424e4fc344b5063d345e18bf73 change-id: 20250224-hybrid-01d5ff47edd2 Best regards, -- Akihiko Odaki <[email protected]>

