All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kouya Shimura <kouya@jp.fujitsu.com>
To: xen-devel@lists.xen.org
Subject: [PATCH] x86/hvm: fix corrupt ACPI PM-Timer during live migration
Date: Tue, 5 Feb 2013 15:12:45 +0900	[thread overview]
Message-ID: <5110A2DD.1080603@jp.fujitsu.com> (raw)

[-- 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

             reply	other threads:[~2013-02-05  6:12 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-05  6:12 Kouya Shimura [this message]
2013-02-12 12:26 ` [PATCH] x86/hvm: fix corrupt ACPI PM-Timer during live migration 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5110A2DD.1080603@jp.fujitsu.com \
    --to=kouya@jp.fujitsu.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.