[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/2] x86/hvm: fix corrupt ACPI PM-Timer during live migration



The ACPI PM-Timer value is broken when a vm is saved.
The function pmtimer_save() calculates the value on its own,
but vcpu->arch.hvm_vcpu.guest_time is not valid (usually zero).

Another problem is a double counting of the PM-Timer value
in failure to save a vm.

This patch corrects the value, and also makes the calculation
more precise.

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/pmtimer.c |   19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c
index 5c25cfb..203a939 100644
--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -85,7 +85,7 @@ void hvm_acpi_sleep_button(struct domain *d)
/* Set the correct value in the timer, accounting for time elapsed
  * since the last time we did that. */
-static void pmt_update_time(PMTState *s)
+static void pmt_update_time(PMTState *s, bool_t update_sci)
 {
     uint64_t curr_gtime, tmp;
     uint32_t tmr_val = s->pm.tmr_val, msb = tmr_val & TMR_VAL_MSB;
@@ -107,7 +107,8 @@ static void pmt_update_time(PMTState *s)
     if ( (tmr_val & TMR_VAL_MSB) != msb )
     {
         s->pm.pm1a_sts |= TMR_STS;
-        pmt_update_sci(s);
+        if ( update_sci )
+            pmt_update_sci(s);
     }
 }
@@ -123,7 +124,7 @@ static void pmt_timer_callback(void *opaque)
     spin_lock(&s->lock);
/* Recalculate the timer and make sure we get an SCI if we need one */
-    pmt_update_time(s);
+    pmt_update_time(s, 1);
/* How close are we to the next MSB flip? */
     pmt_cycles_until_flip = TMR_VAL_MSB - (s->pm.tmr_val & (TMR_VAL_MSB - 1));
@@ -221,7 +222,7 @@ static int handle_pmt_io(
         if ( spin_trylock(&s->lock) )
         {
             /* We hold the lock: update timer value and return it. */
-            pmt_update_time(s);
+            pmt_update_time(s, 1);
             *val = s->pm.tmr_val;
             spin_unlock(&s->lock);
         }
@@ -244,19 +245,11 @@ static int handle_pmt_io(
 static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
 {
     PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
-    uint32_t x, msb = s->pm.tmr_val & TMR_VAL_MSB;
     int rc;
spin_lock(&s->lock); - /* Update the counter to the guest's current time. We always save
-     * with the domain paused, so the saved time should be after the
-     * last_gtime, but just in case, make sure we only go forwards */
-    x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
-    if ( x < 1UL<<31 )
-        s->pm.tmr_val += x;
-    if ( (s->pm.tmr_val & TMR_VAL_MSB) != msb )
-        s->pm.pm1a_sts |= TMR_STS;
+    pmt_update_time(s, 0);
     /* No point in setting the SCI here because we'll already have saved the
      * IRQ and *PIC state; we'll fix it up when we restore the domain */
--
1.7.9.5



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.