kvm_pmu_implemented_counter_mask() derives the counter count from kvm_vcpu_read_pmcr(). For a nested vCPU outside EL2, PMCR_EL0.N reflects MDCR_EL2.HPMN instead of the VM-wide counter count. Consequently, processing a PMU reload while the saved context is L2 can clear and fail to recreate state for counters reserved for EL2. Build the implemented counter mask from nr_pmu_counters instead. Keep the EL-dependent HPMN restriction in kvm_pmu_accessible_counter_mask(), where it controls guest access. Fixes: 600f6fa5c90c ("KVM: arm64: Let kvm_vcpu_read_pmcr() return an EL-dependent value for PMCR_EL0.N") Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Akihiko Odaki Reviewed-by: Fuad Tabba --- arch/arm64/kvm/pmu-emul.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index 950b7a349659..a5ccb6ae44d5 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -317,12 +317,12 @@ u64 kvm_pmu_accessible_counter_mask(struct kvm_vcpu *vcpu) u64 kvm_pmu_implemented_counter_mask(struct kvm_vcpu *vcpu) { - u64 val = FIELD_GET(ARMV8_PMU_PMCR_N, kvm_vcpu_read_pmcr(vcpu)); + u64 n = vcpu->kvm->arch.nr_pmu_counters; - if (val == 0) + if (n == 0) return BIT(ARMV8_PMU_CYCLE_IDX); else - return GENMASK(val - 1, 0) | BIT(ARMV8_PMU_CYCLE_IDX); + return GENMASK(n - 1, 0) | BIT(ARMV8_PMU_CYCLE_IDX); } static void kvm_pmc_enable_perf_event(struct kvm_pmc *pmc) -- 2.55.0