On 09/06/2016 11:31, Alan Jenkins wrote: > diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c > index 1a2da0e..84abb1a 100644 > --- a/arch/x86/kvm/lapic.c > +++ b/arch/x86/kvm/lapic.c > @@ -1273,7 +1273,6 @@ static void apic_timer_expired(struct kvm_lapic *apic) > { > struct kvm_vcpu *vcpu = apic->vcpu; > struct swait_queue_head *q = &vcpu->wq; > - struct kvm_timer *ktimer = &apic->lapic_timer; > > if (atomic_read(&apic->lapic_timer.pending)) > return; > @@ -1283,9 +1282,6 @@ static void apic_timer_expired(struct kvm_lapic *apic) > > if (swait_active(q)) > swake_up(q); > - > - if (apic_lvtt_tscdeadline(apic)) > - ktimer->expired_tscdeadline = ktimer->tscdeadline; > } > > /* > @@ -1922,12 +1918,15 @@ int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) > void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) > { > struct kvm_lapic *apic = vcpu->arch.apic; > + struct kvm_timer *ktimer = &apic->lapic_timer; > > - if (atomic_read(&apic->lapic_timer.pending) > 0) { > + if (atomic_read(&ktimer->pending) > 0) { > kvm_apic_local_deliver(apic, APIC_LVTT); > - if (apic_lvtt_tscdeadline(apic)) > - apic->lapic_timer.tscdeadline = 0; > - atomic_set(&apic->lapic_timer.pending, 0); > + if (apic_lvtt_tscdeadline(apic)) { > + ktimer->expired_tscdeadline = ktimer->tscdeadline; > + ktimer->tscdeadline = 0; > + } > + atomic_set(&ktimer->pending, 0); > } > } > > @@ -2007,6 +2006,71 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) > } > > /* > + * kvm_apic_tsc_update - called when guest or host changes the TSC > + * > + * Update the emulated TSC deadline timer. > + * > + * It is also required if host changes TSC frequency scaling. It is not > + * required when we "catch up" the TSC, because that is maintaining the > + * relationship between TSC and real time. > + */ > +void kvm_apic_tsc_update(struct kvm_vcpu *vcpu) > +{ > + struct kvm_lapic *apic = vcpu->arch.apic; > + struct kvm_timer *ktimer = &apic->lapic_timer; > + > + if (!lapic_in_kernel(vcpu)) > + return; > + > + if (!apic_lvtt_tscdeadline(apic)) > + return; > + > + hrtimer_cancel(&ktimer->timer); > + > + /* > + * Handle when guest TSC is adjusted backwards, just after > + * inject_apic_timer_irqs(). When we hit wait_lapic_expire(), we risk > + * an extended busy-wait. Because ktimer->expired_tscdeadline will > + * have receded further into the future. > + * > + * The guest does not get a chance to run in this window, but the host > + * could modify the TSC at this point. This race could happen when > + * restoring a live snapshot of a VM. > + * > + * Just clear the busy-wait. In theory this could cause a wakeup > + * before the deadline, if the user configured the the busy-wait > + * feature (lapic_advance_timer_ns). We don't expect this to matter: Why not just delay by lapic_advance_timer_ns here? It's usually around 10 nanoseconds, it should be cheap. Paolo -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html