[PATCH v11 05/21] KVM: arm64: PMU: Mask EL2-reserved bits on guest bitmap reads

From: Akihiko Odaki

Date: Sun Sep 20 2026 - 07:25:54 EST


MDCR_EL2.HPMN reserves event counters for EL2. Their bits in the PMU
counter-enable, interrupt-enable, and overflow-status registers must
read as zero at lower exception levels. The guest access handlers
already mask writes, but return the raw bitmap on reads, exposing
EL2-reserved state to the nested guest.

Apply the accessible counter mask to reads in all three handlers,
covering both SET and CLR aliases. Leave the stored state and userspace
migration accesses unchanged so EL2-reserved bits remain preserved.

Fixes: 9a1c58cfefb0 ("KVM: arm64: nv: Adjust range of accessible PMCs according to HPMN")
Closes: https://sashiko.dev/#/patchset/20260914-hybrid-v10-0-92788053a691@xxxxxxxxxxxxxxxxxxxxxx?part=6
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Akihiko Odaki <odaki@xxxxxxxxxxxxxxxxxxxxxx>
---
arch/arm64/kvm/sys_regs.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 40927a4d4409..68339eb8a2bb 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1362,7 +1362,7 @@ static bool access_pmcnten(struct kvm_vcpu *vcpu, struct sys_reg_params *p,

kvm_pmu_reprogram_counter_mask(vcpu, val);
} else {
- p->regval = __vcpu_sys_reg(vcpu, PMCNTENSET_EL0);
+ p->regval = __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask;
}

return true;
@@ -1386,7 +1386,7 @@ static bool access_pminten(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
/* accessing PMINTENCLR_EL1 */
__vcpu_rmw_sys_reg(vcpu, PMINTENSET_EL1, &=, ~val);
} else {
- p->regval = __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
+ p->regval = __vcpu_sys_reg(vcpu, PMINTENSET_EL1) & mask;
}

return true;
@@ -1466,7 +1466,7 @@ static bool access_pmovs(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
/* accessing PMOVSCLR_EL0 */
__vcpu_rmw_sys_reg(vcpu, PMOVSSET_EL0, &=, ~(p->regval & mask));
} else {
- p->regval = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
+ p->regval = __vcpu_sys_reg(vcpu, PMOVSSET_EL0) & mask;
}

return true;

--
2.55.0