[PATCH v22 21/23] KVM: arm64: CCA: Support timers in realm RECs

Gavin Shan gshan at redhat.com
Mon Oct 5 22:44:39 PDT 2026


On 10/5/26 7:07 PM, Suzuki K Poulose wrote:
> From: Steven Price <steven.price at arm.com>
> 
> 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 making sure the values are in sync for KVM.
> 
> Also, RMM doesn't support injecting virtual interrupts backed by Physical
> interrupts. So, use the existing software resampling mechanims for Realm
                                                        ^^^^^^^^^
typo: mechanism

> timer interrupts.
> 
> Signed-off-by: Steven Price <steven.price at arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>   arch/arm64/kvm/arch_timer.c | 22 ++++++++++++++++++++--
>   1 file changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index a45845f4ae4ea..428709f499205 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -56,11 +56,25 @@ static unsigned long kvm_arch_timer_get_irq_flags(void)
>   	return kvm_vgic_global_state.no_hw_deactivation ? VGIC_IRQ_SW_RESAMPLE : 0;
>   }
>   
> +static unsigned long kvm_realm_timer_get_irq_flags(void)
> +{
> +	/*
> +	 * RMI_REC_ENTER rejects LRs with the HW bit set, so use the existing
> +	 * software resampling mechanism for Realm timer interrupts.
> +	 */
> +	return VGIC_IRQ_SW_RESAMPLE;
> +}
> +
>   static const struct irq_ops arch_timer_irq_ops = {
>   	.get_flags	 = kvm_arch_timer_get_irq_flags,
>   	.get_input_level = kvm_arch_timer_get_input_level,
>   };
>   
> +static const struct irq_ops realm_timer_irq_ops = {
> +	.get_flags	 = kvm_realm_timer_get_irq_flags,
> +	.get_input_level = kvm_arch_timer_get_input_level,
> +};
> +
>   static const struct irq_ops arch_timer_irq_ops_vgic_v5 = {
>   	.get_input_level = kvm_arch_timer_get_input_level,
>   	.queue_irq_unlock = vgic_v5_ppi_queue_irq_unlock,
> @@ -1617,8 +1631,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>   
>   	get_timer_map(vcpu, &map);
>   
> -	ops = vgic_is_v5(vcpu->kvm) ? &arch_timer_irq_ops_vgic_v5 :
> -				      &arch_timer_irq_ops;
> +	if (vcpu_is_rec(vcpu))
> +		ops = &realm_timer_irq_ops;
> +	else if (vgic_is_v5(vcpu->kvm))
> +		ops = &arch_timer_irq_ops_vgic_v5;
> +	else
> +		ops = &arch_timer_irq_ops;
>   
>   	for (int i = 0; i < nr_timers(vcpu); i++)
>   		kvm_vgic_set_irq_ops(vcpu, timer_irq(vcpu_get_timer(vcpu, i)), ops);




More information about the linux-arm-kernel mailing list