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

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



>>> On 05.02.13 at 07:12, Kouya Shimura <kouya@xxxxxxxxxxxxxx> wrote:
>--- 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);

Single space only please.

>+}
>+
>+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 )

How is guest_time being (non-)zero an indication of mode being
delay_for_missed_ticks? I think you should check for the mode
explicitly, as the value here being zero can just be an effect of
a large enough negative v->arch.hvm_vcpu.stime_offset.

And besides that you don't explain why the update being done
here is unnecessary in other modes - all you explain is that the
way it's being done in those modes is wrong.

>+    {
>+        /* 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",

While probably fine this way for -unstable, please nevertheless
use the correct PRId64 here (both to be formally correct and to
ease eventual backporting).

Jan

>+                    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);
> 


_______________________________________________
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®.