All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/hvm: fix corrupt ACPI PM-Timer during live migration
@ 2013-02-05  6:12 Kouya Shimura
  2013-02-12 12:26 ` Jan Beulich
  0 siblings, 1 reply; 22+ messages in thread
From: Kouya Shimura @ 2013-02-05  6:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: Type: text/plain, Size: 466 bytes --]

The value of ACPI PM-Timer may be broken on save unless the timer mode
is delay_for_missed_ticks.
With other timer modes, vcpu->arch.hvm_vcpu.guest_time is always zero
and the adjustment from its value is wrong.

This patch fixes the saved value of ACPI PM-Timer:
- don't adjust the PM-Timer if vcpu->arch.hvm_vcpu.guest_time is zero.
- consolidate calculations of PM-Timer to one function. more precise on save.

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>

[-- Attachment #2: fix_corrupt_saved_pmtimer.patch --]
[-- Type: text/x-patch, Size: 3549 bytes --]

diff -r 5af4f2ab06f3 xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c	Tue Jan 22 09:33:10 2013 +0100
+++ b/xen/arch/x86/hvm/pmtimer.c	Tue Feb 05 10:26:13 2013 +0900
@@ -84,28 +84,31 @@ void hvm_acpi_sleep_button(struct domain
 }
 
 /* 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)
+ * since the last time we did that.
+ * return true if the counter's MSB has changed. */
+static bool_t pmt_count_up_and_test_msb(PMTState *s, uint64_t gtime)
 {
-    uint64_t curr_gtime, tmp;
     uint32_t tmr_val = s->pm.tmr_val, msb = tmr_val & TMR_VAL_MSB;
-    
-    ASSERT(spin_is_locked(&s->lock));
+    uint64_t tmp = ((gtime - s->last_gtime) * s->scale) + s->not_accounted;
 
-    /* Update the timer */
-    curr_gtime = hvm_get_guest_time(s->vcpu);
-    tmp = ((curr_gtime - s->last_gtime) * s->scale) + s->not_accounted;
     s->not_accounted = (uint32_t)tmp;
     tmr_val += tmp >> 32;
     tmr_val &= TMR_VAL_MASK;
-    s->last_gtime = curr_gtime;
+    s->last_gtime = gtime;
 
     /* Update timer value atomically wrt lock-free reads in handle_pmt_io(). */
     *(volatile uint32_t *)&s->pm.tmr_val = tmr_val;
 
-    /* If the counter's MSB has changed, set the status bit */
-    if ( (tmr_val & TMR_VAL_MSB) != msb )
+    return  ((tmr_val & TMR_VAL_MSB) != msb);
+}
+
+static void pmt_update_time(PMTState *s)
+{
+    ASSERT(spin_is_locked(&s->lock));
+
+    if ( pmt_count_up_and_test_msb(s, hvm_get_guest_time(s->vcpu)) )
     {
+        /* MSB has changed, set the status bit */
         s->pm.pm1a_sts |= TMR_STS;
         pmt_update_sci(s);
     }
@@ -244,21 +247,34 @@ 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;
+    uint64_t guest_time;
     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;
-    /* 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 */
+    guest_time = s->vcpu->arch.hvm_vcpu.guest_time;
+    /* Update the counter to the guest's current time only if the
+     * timer mode is delay_for_missed_ticks */
+    if ( guest_time != 0 )
+    {
+        /* 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 */
+        if ( (s64)guest_time - (s64)s->last_gtime < 0)
+        {
+            dprintk(XENLOG_WARNING,
+                    "Last update of PMT is ahead of guest's time by %ld\n",
+                    s->last_gtime - guest_time);
+        }
+        else
+        {
+            if ( pmt_count_up_and_test_msb(s, guest_time) )
+                s->pm.pm1a_sts |= TMR_STS;
+            /* 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 */
+        }
+    }
 
     rc = hvm_save_entry(PMTIMER, 0, h, &s->pm);
 

[-- Attachment #3: Type: text/plain, Size: 126 bytes --]

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

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2013-05-16 10:38 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-05  6:12 [PATCH] x86/hvm: fix corrupt ACPI PM-Timer during live migration Kouya Shimura
2013-02-12 12:26 ` Jan Beulich
2013-02-14  6:09   ` Kouya Shimura
2013-02-15 16:45     ` Jan Beulich
2013-02-20  7:42       ` Kouya Shimura
2013-03-07 15:58         ` Jan Beulich
2013-03-08  7:59           ` Kouya Shimura
2013-03-21  7:31           ` Kouya Shimura
2013-03-21  8:05             ` Jan Beulich
     [not found]           ` <514A9BC4.40508@jp.fujitsu.com>
2013-03-21  7:32             ` [PATCH 1/2] x86/hvm: prevent guest's timers from going backwards, when timer_mode=0 Kouya Shimura
2013-03-21  7:32             ` [PATCH 2/2] x86/hvm: fix corrupt ACPI PM-Timer during live migration Kouya Shimura
2013-03-21 10:01               ` Jan Beulich
2013-03-22  1:12                 ` Kouya Shimura
2013-03-22  8:02                   ` Jan Beulich
2013-05-15 14:23                     ` Alex Bligh
2013-05-15 14:31                       ` Jan Beulich
2013-05-15 14:49                         ` Alex Bligh
2013-05-15 14:54                           ` Jan Beulich
2013-05-16  5:29                             ` Kouya Shimura
2013-05-16 10:38                               ` Alex Bligh
2013-05-16  5:27                         ` Kouya Shimura
2013-05-16  9:54                           ` Tim Deegan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.