X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=arch%2Fx86%2Fkvm%2Flapic.c;h=b5cd8465d44f6cb99a9ae705cf2f44f3c310a1ac;hb=b357bf6023a948cf6a9472f07a1b0caac0e4f8e8;hp=776391cf69a5196ae0fb33a6abbb496fc167f2fa;hpb=766d3571d8e50d3a73b77043dc632226f9e6b389;p=tomoyo%2Ftomoyo-test1.git diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 776391cf69a5..b5cd8465d44f 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1522,11 +1522,23 @@ static bool set_target_expiration(struct kvm_lapic *apic) static void advance_periodic_target_expiration(struct kvm_lapic *apic) { - apic->lapic_timer.tscdeadline += - nsec_to_cycles(apic->vcpu, apic->lapic_timer.period); + ktime_t now = ktime_get(); + u64 tscl = rdtsc(); + ktime_t delta; + + /* + * Synchronize both deadlines to the same time source or + * differences in the periods (caused by differences in the + * underlying clocks or numerical approximation errors) will + * cause the two to drift apart over time as the errors + * accumulate. + */ apic->lapic_timer.target_expiration = ktime_add_ns(apic->lapic_timer.target_expiration, apic->lapic_timer.period); + delta = ktime_sub(apic->lapic_timer.target_expiration, now); + apic->lapic_timer.tscdeadline = kvm_read_l1_tsc(apic->vcpu, tscl) + + nsec_to_cycles(apic->vcpu, delta); } static void start_sw_period(struct kvm_lapic *apic)