On Mon, 20 Jul 2026 at 06:39, Akihiko Odaki <[email protected]> wrote: > > 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 <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > --- > 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 b4b877f31097..5281d37634a0 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 > >

