Re: [PATCH v2 3/3] KVM: arm64: Disable host PMU counters for protected guests
From: Marc Zyngier
Date: Wed Oct 28 2026 - 08:58:04 EST
On Wed, 28 Oct 2026 11:07:39 +0000,
Fuad Tabba <fuad.tabba@xxxxxxxxx> wrote:
>
> A protected guest has no PMU, and EL2 clears MDCR_EL2.HPME for it.
> However, HPME has no effect, since __pkvm_vcpu_load() sets HPMN to cover
> every event counter, and HPME never covers the cycle or instruction
> counter. The counters the host has enabled therefore keep counting the
> guest.
>
> Stop them in the world switch while a protected guest runs, reading
> PMCNTENSET_EL0 rather than trusting the host-controlled events mask.
> Gate this on system_supports_pmuv3(), as __activate_traps_common() does
> for PMUSERENR_EL0.
>
> Side channels are outside pKVM's threat model, so this is hardening
> rather than a fix.
>
> Reported-by: Oculytic <oculytic@xxxxxxxxx>
> Signed-off-by: Fuad Tabba <fuad.tabba@xxxxxxxxx>
> ---
> arch/arm64/kvm/hyp/nvhe/switch.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index 91e1edf40bcd2..f602154ab49b5 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -175,6 +175,26 @@ static void __pmu_switch_to_host(struct kvm_vcpu *vcpu)
> #define __pmu_switch_to_host(v) do {} while (0)
> #endif
>
> +static u64 __pmu_stop_host_counters(struct kvm_vcpu *vcpu)
> +{
> + u64 pmcnten;
> +
> + if (!vcpu_is_protected(vcpu) || !system_supports_pmuv3())
> + return 0;
> +
> + pmcnten = read_sysreg(pmcntenset_el0);
> + if (pmcnten)
> + write_sysreg(pmcnten, pmcntenclr_el0);
It feels a bit odd to change the individual counter enables, rather
than just use PMCR_EL0.E, which is designed for this purpose.
It probably doesn't change much, but it'd certainly make the intent a
bit more obvious. Or am I missing something?
Thanks,
M.
--
Without deviation from the norm, progress is not possible.