The static variables pmu_version, num_pmu_gp_counters, and
num_pmu_fixed_counters persist across different VCPU initializations.
When kvm_init_pmu_info() returns early (e.g., when PMU is disabled or
there's a vendor mismatch), these variables retain stale values from
previous initializations.
This causes crashes during guest reboots, particularly with Windows XP,
when kvm_put_msrs() attempts to write PMU MSRs based on the stale
pmu_version value for a CPU that doesn't actually support PMU.
Fix this by resetting the PMU state variables to 0 at the start of
kvm_init_pmu_info() to ensure clean initialization for each VCPU.
Fixes: 4c7f05232c ("target/i386/kvm: reset AMD PMU registers during VM reset")
Signed-off-by: GitHub Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
---
target/i386/kvm/kvm.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 9f1a4d4cbb..c636f1f487 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2193,6 +2193,14 @@ static void kvm_init_pmu_info(struct kvm_cpuid2 *cpuid,
X86CPU *cpu)
{
CPUX86State *env = &cpu->env;
+ /*
+ * Reset PMU state to avoid stale values from previous VCPU
+ * initializations affecting subsequent ones.
+ */
+ pmu_version = 0;
+ num_pmu_gp_counters = 0;
+ num_pmu_fixed_counters = 0;
+
/*
* If KVM_CAP_PMU_CAPABILITY is not supported, there is no way to
* disable the AMD PMU virtualization.
--
2.53.0