    kvm: qemu: fix local apic timer save/restore when inactive
    
    When the local apic timer is inactive (not initialized) or expired in one
    shot mode, it is not reasonable to restart this timer at restore time. This
    patch uses current count register to communicate the state of the timer
    and save/restore the timer according to it
    
    Signed-off-by: Qing He <qing.he@intel.com>


---
 qemu/hw/apic.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/qemu/hw/apic.c b/qemu/hw/apic.c
index f479061..82175df 100644
--- a/qemu/hw/apic.c
+++ b/qemu/hw/apic.c
@@ -768,6 +768,7 @@ static void kvm_kernel_lapic_save_to_user(APICState *s)
     struct kvm_lapic_state apic;
     struct kvm_lapic_state *kapic = &apic;
     int i, v;
+    int tmcct;
 
     kvm_get_lapic(kvm_context, s->cpu_env->cpu_index, kapic);
 
@@ -793,8 +794,14 @@ static void kvm_kernel_lapic_save_to_user(APICState *s)
     v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
     s->count_shift = (v + 1) & 7;
 
-    s->initial_count_load_time = qemu_get_clock(vm_clock);
-    apic_timer_update(s, s->initial_count_load_time);
+    tmcct = kapic_reg(kapic, 0x39);
+    if (tmcct != 0) {
+        s->initial_count_load_time = qemu_get_clock(vm_clock);
+        apic_timer_update(s, s->initial_count_load_time);
+    }
+    else {
+        qemu_del_timer(s->timer);
+    }
 }
 
 static void kvm_kernel_lapic_load_from_user(APICState *s)
@@ -822,6 +829,13 @@ static void kvm_kernel_lapic_load_from_user(APICState *s)
     kapic_set_reg(klapic, 0x38, s->initial_count);
     kapic_set_reg(klapic, 0x3e, s->divide_conf);
 
+    if (qemu_timer_pending(s->timer)) {
+        kapic_set_reg(klapic, 0x39, s->initial_count);
+    }
+    else {
+        kapic_set_reg(klapic, 0x39, 0);
+    }
+
     kvm_set_lapic(kvm_context, s->cpu_env->cpu_index, klapic);
 }
 #endif

