Loading arch/x86/kvm/lapic.c +27 −13 Original line number Diff line number Diff line Loading @@ -1501,24 +1501,38 @@ static void cancel_hv_timer(struct kvm_lapic *apic) preempt_enable(); } static bool start_hv_timer(struct kvm_lapic *apic) static bool __start_hv_timer(struct kvm_lapic *apic) { u64 tscdeadline = apic->lapic_timer.tscdeadline; struct kvm_timer *ktimer = &apic->lapic_timer; int r; if ((atomic_read(&apic->lapic_timer.pending) && !apic_lvtt_period(apic)) || kvm_x86_ops->set_hv_timer(apic->vcpu, tscdeadline)) { if (apic->lapic_timer.hv_timer_in_use) cancel_hv_timer(apic); } else { apic->lapic_timer.hv_timer_in_use = true; hrtimer_cancel(&apic->lapic_timer.timer); if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending)) return false; r = kvm_x86_ops->set_hv_timer(apic->vcpu, ktimer->tscdeadline); if (r < 0) return false; ktimer->hv_timer_in_use = true; hrtimer_cancel(&ktimer->timer); /* In case the sw timer triggered in the window */ if (atomic_read(&apic->lapic_timer.pending) && !apic_lvtt_period(apic)) /* * Also recheck ktimer->pending, in case the sw timer triggered in * the window. For periodic timer, leave the hv timer running for * simplicity, and the deadline will be recomputed on the next vmexit. */ if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending)) return false; return true; } static bool start_hv_timer(struct kvm_lapic *apic) { if (!__start_hv_timer(apic)) { if (apic->lapic_timer.hv_timer_in_use) cancel_hv_timer(apic); } trace_kvm_hv_timer_state(apic->vcpu->vcpu_id, apic->lapic_timer.hv_timer_in_use); return apic->lapic_timer.hv_timer_in_use; Loading Loading
arch/x86/kvm/lapic.c +27 −13 Original line number Diff line number Diff line Loading @@ -1501,24 +1501,38 @@ static void cancel_hv_timer(struct kvm_lapic *apic) preempt_enable(); } static bool start_hv_timer(struct kvm_lapic *apic) static bool __start_hv_timer(struct kvm_lapic *apic) { u64 tscdeadline = apic->lapic_timer.tscdeadline; struct kvm_timer *ktimer = &apic->lapic_timer; int r; if ((atomic_read(&apic->lapic_timer.pending) && !apic_lvtt_period(apic)) || kvm_x86_ops->set_hv_timer(apic->vcpu, tscdeadline)) { if (apic->lapic_timer.hv_timer_in_use) cancel_hv_timer(apic); } else { apic->lapic_timer.hv_timer_in_use = true; hrtimer_cancel(&apic->lapic_timer.timer); if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending)) return false; r = kvm_x86_ops->set_hv_timer(apic->vcpu, ktimer->tscdeadline); if (r < 0) return false; ktimer->hv_timer_in_use = true; hrtimer_cancel(&ktimer->timer); /* In case the sw timer triggered in the window */ if (atomic_read(&apic->lapic_timer.pending) && !apic_lvtt_period(apic)) /* * Also recheck ktimer->pending, in case the sw timer triggered in * the window. For periodic timer, leave the hv timer running for * simplicity, and the deadline will be recomputed on the next vmexit. */ if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending)) return false; return true; } static bool start_hv_timer(struct kvm_lapic *apic) { if (!__start_hv_timer(apic)) { if (apic->lapic_timer.hv_timer_in_use) cancel_hv_timer(apic); } trace_kvm_hv_timer_state(apic->vcpu->vcpu_id, apic->lapic_timer.hv_timer_in_use); return apic->lapic_timer.hv_timer_in_use; Loading