[PATCH v8 5/7] KVM: arm64: PMU: Implement fixed-counters-only emulation
Akihiko Odaki
odaki at rsg.ci.i.u-tokyo.ac.jp
Wed Jul 8 02:43:32 PDT 2026
On 2026/07/08 3:02, Oliver Upton wrote:
> On Tue, Jul 07, 2026 at 09:52:49PM +0900, Akihiko Odaki wrote:
>> On 2026/07/07 20:23, Akihiko Odaki wrote:
>>> On 2026/07/07 3:23, Oliver Upton wrote:
>>>> Just detect the changing PMU implementation here, KVM_REQ_RELOAD_PMU
>>>> will need to detect the PMCs that require an update anyway. Stash the
>>>> last cpu in kvm_arch_vcpu_load() and pass it to this:
>>>>
>>>> void kvm_vcpu_load_pmu(struct kvm_vcpu *vcpu, int last_cpu)
>>>> {
>>>> if (!kvm_pmu_fixed_counters_only(vcpu->kvm) || vcpu->cpu == last_cpu)
>>>> return;
>>>>
>>>> if (kvm_pmu_probe_armpmu(vcpu->cpu) !=
>>>> kvm_pmu_probe_armpmu(last_cpu))
>>>> kvm_make_request(KVM_REQ_RELOAD_PMU);
>>>> }
>>>
>>> It is a nice way to simplify the code and to avoid hardcoding
>>> ARMV8_PMU_INSTR_IDX. I'll use the code for the next version.
>>
>> I tried this but unfortunately it doesn't seem to work. kvm_arch_vcpu_put()
>> sets vcpu->cpu to -1 so we cannot simply read it to get the last cpu in
>> kvm_arch_vcpu_load().
>
> Urgh, there's no reason for doing that any more. Let's fix it, I want a
> straightforward way to detect pCPU migrations. There may be other
> reasons for using it in the future.
>
> Untested, but could you give this a whirl?
It looks good to me. I'll test it and include it in the next version.
Regards,
Akihiko Odaki
>
> From bb5af058030aada66f5c9eafa54db604979acf55 Mon Sep 17 00:00:00 2001
> From: Oliver Upton <oupton at kernel.org>
> Date: Tue, 7 Jul 2026 09:50:00 -0700
> Subject: [PATCH] KVM: arm64: Don't clear vcpu->cpu in kvm_arch_vcpu_put()
>
> commit e9b152cb957c ("arm/arm64: kvm: Set vcpu->cpu to -1 on vcpu_put")
> reset vcpu->cpu in order for the VGIC to determine if there was any vCPU
> running at the time of access. The VGIC has gone through an entire
> rewrite since then, and with commit 7d450e282171 ("KVM: arm/arm64:
> vgic-new: Add userland access to VGIC dist registers") the user
> accessors just grab all vCPU mutexes instead.
>
> Drop this remaining vestige such that kvm_arch_vcpu_load() can properly
> detect a CPU migration. While at it, rework kvm_reset_vcpu() to do a
> much more pedantic check that the provided vCPU is actually what's
> running on the present CPU.
>
> Signed-off-by: Oliver Upton <oupton at kernel.org>
> ---
> arch/arm64/kvm/arm.c | 1 -
> arch/arm64/kvm/reset.c | 15 ++++++++++-----
> 2 files changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 50adfff75be8..735acc42b50b 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -749,7 +749,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> kvm_arm_vmid_clear_active();
>
> vcpu_clear_on_unsupported_cpu(vcpu);
> - vcpu->cpu = -1;
> }
>
> static void __kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu)
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index b963fd975aac..6aba085c0673 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -190,7 +190,8 @@ static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu)
> void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> {
> struct vcpu_reset_state reset_state;
> - bool loaded;
> + struct kvm_vcpu *running;
> + bool loaded = false;
> u32 pstate;
>
> spin_lock(&vcpu->arch.mp_state_lock);
> @@ -198,10 +199,15 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> vcpu->arch.reset_state.reset = false;
> spin_unlock(&vcpu->arch.mp_state_lock);
>
> - preempt_disable();
> - loaded = (vcpu->cpu != -1);
> - if (loaded)
> + guard(preempt)();
> +
> + if ((running = kvm_get_running_vcpu())) {
> + if (KVM_BUG_ON(running != vcpu, vcpu->kvm))
> + return;
> +
> + loaded = true;
> kvm_arch_vcpu_put(vcpu);
> + }
>
> if (!kvm_arm_vcpu_sve_finalized(vcpu)) {
> if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE))
> @@ -269,7 +275,6 @@ void kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>
> if (loaded)
> kvm_arch_vcpu_load(vcpu, smp_processor_id());
> - preempt_enable();
> }
>
> u32 kvm_get_pa_bits(struct kvm *kvm)
More information about the linux-arm-kernel
mailing list