Guest-Hypervisor forwards the timer interrupt to Guest-Guest, if it is enabled, unmasked and ISTATUS bit of register CNTV_CTL_EL0 is set for a loaded timer. For NV2 implementation, the Host-Hypervisor is not emulating the ISTATUS bit while forwarding the Emulated Vtimer Interrupt to Guest-Hypervisor. This results in the drop of interrupt from Guest-Hypervisor, where as Host Hypervisor marked it as an active interrupt and expecting Guest-Guest to consume and acknowledge. Due to this, some of the Guest-Guest vCPUs are stuck in Idle thread and rcu soft lockups are seen. This issue is not seen with NV1 case since the register CNTV_CTL_EL0 read trap handler is emulating the ISTATUS bit. Adding code to set/emulate the ISTATUS when the emulated timers are fired. Signed-off-by: Ganapatrao Kulkarni <gankulkarni@xxxxxxxxxxxxxxxxxxxxxx> --- arch/arm64/kvm/arch_timer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 27a6ec46803a..0b32d943d2d5 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -63,6 +63,7 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu, struct arch_timer_context *timer, enum kvm_arch_timer_regs treg); static bool kvm_arch_timer_get_input_level(int vintid); +static u64 read_timer_ctl(struct arch_timer_context *timer); static struct irq_ops arch_timer_irq_ops = { .get_input_level = kvm_arch_timer_get_input_level, @@ -356,6 +357,8 @@ static enum hrtimer_restart kvm_hrtimer_expire(struct hrtimer *hrt) return HRTIMER_RESTART; } + /* Timer emulated, emulate ISTATUS also */ + timer_set_ctl(ctx, read_timer_ctl(ctx)); kvm_timer_update_irq(vcpu, true, ctx); return HRTIMER_NORESTART; } @@ -458,6 +461,8 @@ static void timer_emulate(struct arch_timer_context *ctx) trace_kvm_timer_emulate(ctx, should_fire); if (should_fire != ctx->irq.level) { + /* Timer emulated, emulate ISTATUS also */ + timer_set_ctl(ctx, read_timer_ctl(ctx)); kvm_timer_update_irq(ctx->vcpu, should_fire, ctx); return; } -- 2.33.1