Re: [PATCH v15 13/37] KVM: arm64: CCA: Support timers in realm RECs
From: Marc Zyngier
Date: Wed Jul 29 2026 - 07:24:39 EST
On Wed, 29 Jul 2026 11:47:03 +0100,
Steven Price <steven.price@xxxxxxx> wrote:
>
> On 27/07/2026 10:21, Marc Zyngier wrote:
> > On Wed, 15 Jul 2026 15:28:15 +0100,
> > Steven Price <steven.price@xxxxxxx> wrote:
> >>
> >> The RMM keeps track of the timer while the realm REC is running, but on
> >> exit to the normal world KVM is responsible for handling the timers.
> >>
> >> A later patch adds the support for propagating the timer values from the
> >> exit data structure and calling kvm_realm_timers_update().
> >>
> >> Signed-off-by: Steven Price <steven.price@xxxxxxx>
> >> ---
> >> Changes since v14:
> >> * Special case in kvm_timer_vcpu_load()/kvm_timer_vcpu_put() the timer
> >> handling.
> >> Changes since v12:
> >> * Adapt to upstream changes.
> >> Changes since v11:
> >> * Drop the kvm_is_realm() check from timer_set_offset(). We already
> >> ensure that the offset is 0 when calling the function.
> >> Changes since v10:
> >> * KVM_CAP_COUNTER_OFFSET is now already hidden by a previous patch.
> >> Changes since v9:
> >> * No need to move the call to kvm_timer_unblocking() in
> >> kvm_timer_vcpu_load().
> >> Changes since v7:
> >> * Hide KVM_CAP_COUNTER_OFFSET for realm guests.
> >> ---
> >> arch/arm64/kvm/arch_timer.c | 38 +++++++++++++++++++++++++++++++++---
> >> include/kvm/arm_arch_timer.h | 2 ++
> >> 2 files changed, 37 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> >> index 4155fe89b58a..fdd68f1f5b7b 100644
> >> --- a/arch/arm64/kvm/arch_timer.c
> >> +++ b/arch/arm64/kvm/arch_timer.c
> >> @@ -482,6 +482,20 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
> >> timer_ctx);
> >> }
> >>
> >> +void kvm_realm_timers_update(struct kvm_vcpu *vcpu)
> >> +{
> >> + struct arch_timer_cpu *arch_timer = &vcpu->arch.timer_cpu;
> >> + int i;
> >> +
> >> + for (i = 0; i < NR_KVM_EL0_TIMERS; i++) {
> >> + struct arch_timer_context *timer = &arch_timer->timers[i];
> >> + bool status = timer_get_ctl(timer) & ARCH_TIMER_CTRL_IT_STAT;
> >> + bool level = kvm_timer_enabled(timer) && status;
> >> +
> >> + kvm_timer_update_irq(vcpu, level, timer);
> >> + }
> >> +}
> >> +
> >
> > Why do we need this? What is so special about CCA that it cannot use
> > the existing timer flow?
>
> CCA is a little special because the timer context is owned by the RMM
> while the realm is executing. It's the RMM which actually loads/saves
> the timer registers not KVM.
>
> The RMM returns some of the timer state on every exit, and the host is
> responsible for updating the interrupt status (as the host controls the
> GIC emulation).
But KVM relies on the timers being live when the vcpu is loaded. So
the first port of call should be for CCA to adapt to KVM, and not the
other way around.
You can always make sure that the timers are in the registers at the
point where you reach the KVM code.
M.
--
Without deviation from the norm, progress is not possible.