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


Reply via email to