|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |