
    cleanup:
    	last_update should precisely reflect the time
    	when an hrtimer is fired, and store the period
    	of apic timer to avoid calculation each time.
    
    Signed-off-by: Yaozu (Eddie) Dong <Eddie.Dong@intel.com>

diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
index 44e1fa4..ed6d20a 100644
--- a/drivers/kvm/irq.h
+++ b/drivers/kvm/irq.h
@@ -111,6 +111,7 @@ struct kvm_lapic {
 	struct kvm_io_device dev;
 	struct {
 		unsigned long pending;
+		s64 period;	/* unit: ns */
 		u32 divide_count;
 		ktime_t last_update;
 		struct hrtimer dev;
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index fc53e88..352b8a7 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -627,11 +627,10 @@ static void apic_mmio_write(struct kvm_io_device *this,
 	case APIC_TMICT:
 		{
 			ktime_t now = apic->timer.dev.base->get_time();
-			u32 offset;
 
 			apic_set_reg(apic, APIC_TMICT, val);
 			apic->timer.last_update = now;
-			offset =
+			apic->timer.period =
 			    APIC_BUS_CYCLE_NS * apic->timer.divide_count * val;
 
 			/* Make sure the lock ordering is coherent */
@@ -861,7 +860,6 @@ EXPORT_SYMBOL_GPL(kvm_lapic_get_regs);
 static int __apic_timer_fn(struct kvm_lapic *apic)
 {
 	u32 vector;
-	ktime_t now;
 	int result = 0;
 
 	if (unlikely(!apic_enabled(apic) ||
@@ -872,8 +870,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
 	}
 
 	vector = apic_lvt_vector(apic, APIC_LVTT);
-	now = apic->timer.dev.base->get_time();
-	apic->timer.last_update = now;
+	apic->timer.last_update = apic->timer.dev.expires;
 	apic->timer.pending++;
 	__apic_accept_irq(apic, APIC_DM_FIXED, vector, 1, 0);
 
@@ -884,7 +881,9 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
 		offset = APIC_BUS_CYCLE_NS * apic->timer.divide_count * tmict;
 
 		result = 1;
-		apic->timer.dev.expires = ktime_add_ns(now, offset);
+		apic->timer.dev.expires = ktime_add_ns(
+					apic->timer.dev.expires,
+					apic->timer.period);
 	}
 
 	return result;
