Re: [PATCH v15 13/37] KVM: arm64: CCA: Support timers in realm RECs
Steven Price <[email protected]> Thu, 30 Jul 2026 09:47:27 +0100
| Newsgroups | dev.linux.lists.linux-coco,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 29/07/2026 11:58, Marc Zyngier wrote: > On Wed, 29 Jul 2026 11:47:03 +0100, > Steven Price <[email protected]> wrote: >> >> On 27/07/2026 10:21, Marc Zyngier wrote: >>> On Wed, 15 Jul 2026 15:28:15 +0100, >>> Steven Price <[email protected]> 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 <[email protected]> >>>> --- >>>> 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. Indeed if you'd prefer that I can modify the code to load the timer state into the registers in the Linux CCA code before reaching the generic KVM code. It's a little weird from an overall point of view (the RMM saves the state into memory, and then Linux reloads it just to save it again), but I don't see any implementation issues. But a quick go at implementing this does indeed seem to save us a bit of code, so I'll include this in the next posting. Thanks, Steve