/* * Schedule the background timer before calling kvm_vcpu_block, so that this * thread is removed from its waitqueue and made runnable when there's a timer * interrupt to handle. */ void kvm_timer_schedule(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; u64 ns; cycle_t cval, now; BUG_ON(timer_is_armed(timer)); /* * No need to schedule a background timer if the guest timer has * already expired, because kvm_vcpu_block will return before putting * the thread to sleep. */ if (kvm_timer_should_fire(vcpu)) return; /* * If the timer is not capable of raising interrupts (disabled or * masked), then there's no more work for us to do. */ if (!kvm_timer_irq_can_fire(vcpu)) return; /* The timer has not yet expired, schedule a background timer */ cval = timer->cntv_cval; now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; ns = cyclecounter_cyc2ns(timecounter->cc, cval - now, timecounter->mask, &timecounter->frac); timer_arm(timer, ns); }
/* * Check if there was a change in the timer state (should we raise or lower * the line level to the GIC). */ static void kvm_timer_update_state(struct kvm_vcpu *vcpu) { struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; /* * If userspace modified the timer registers via SET_ONE_REG before * the vgic was initialized, we mustn't set the timer->irq.level value * because the guest would never see the interrupt. Instead wait * until we call this function from kvm_timer_flush_hwstate. */ if (!vgic_initialized(vcpu->kvm)) return; if (kvm_timer_should_fire(vcpu) != timer->irq.level) kvm_timer_update_irq(vcpu, !timer->irq.level); }
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) { return kvm_timer_should_fire(vcpu); }