KVM: arm64: Handle ID_AA64DFR0_EL1.PMUVer == NI in __kvm_pmu_event_mask()

When userspace initializes a vCPU with KVM_ARM_VCPU_PMU_V3 but sets
ID_AA64DFR0_EL1.PMUVer to NI (0) or IMP_DEF (0xf, which is sanitized to
NI), resetting the vCPU invokes reset_pmevtyper() and calls
kvm_pmu_evtyper_mask(). Because __kvm_pmu_event_mask() does not handle
ID_AA64DFR0_EL1_PMUVer_NI, it triggers a WARN_ONCE("Unknown PMU version
0").

Explicitly handle ID_AA64DFR0_EL1_PMUVer_NI in __kvm_pmu_event_mask() by
returning an event mask of 0, and drop the redundant kvm_vcpu_has_pmu()
check in reset_pmevtyper().

Fixes: bc512d6a9b ("KVM: arm64: Make PMEVTYPER<n>_EL0.NSH RES0 if EL2 isn't advertised")
Suggested-by: Oliver Upton <oupton@kernel.org>
Assisted-by: LLM
Signed-off-by: Colton Lewis <coltonlewis@google.com>
Link: https://patch.msgid.link/20260930211834.2773546-2-coltonlewis@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
Colton Lewis 2026-09-30 21:18:33 +00:00 committed by Marc Zyngier
parent 8642afb74b
commit aa41a7c3be
2 changed files with 4 additions and 5 deletions

View File

@ -50,8 +50,11 @@ static u32 __kvm_pmu_event_mask(unsigned int pmuver)
case ID_AA64DFR0_EL1_PMUVer_V3P5:
case ID_AA64DFR0_EL1_PMUVer_V3P7:
return GENMASK(15, 0);
default: /* Shouldn't be here, just for sanity */
default:
/* Shouldn't be here, just for sanity */
WARN_ONCE(1, "Unknown PMU version %d\n", pmuver);
fallthrough;
case ID_AA64DFR0_EL1_PMUVer_NI:
return 0;
}
}

View File

@ -1058,10 +1058,6 @@ static u64 reset_pmevcntr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
static u64 reset_pmevtyper(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
{
/* This thing will UNDEF, who cares about the reset value? */
if (!kvm_vcpu_has_pmu(vcpu))
return 0;
reset_unknown(vcpu, r);
__vcpu_rmw_sys_reg(vcpu, r->reg, &=, kvm_pmu_evtyper_mask(vcpu->kvm));