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

[Xen-changelog] [xen stable-4.4] x86/hvm: fix saved pmtimer and hpet values



commit fbb3881ace18434b9490b74c067fd67bd9d681a5
Author:     Kouya Shimura <kouya@xxxxxxxxxxxxxx>
AuthorDate: Thu Oct 8 12:41:22 2015 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Oct 8 12:41:22 2015 +0200

    x86/hvm: fix saved pmtimer and hpet values
    
    The ACPI PM timer is sometimes broken on live migration.
    Since vcpu->arch.hvm_vcpu.guest_time is always zero in other than
    "delay for missed ticks mode". Even in "delay for missed ticks mode",
    vcpu's guest_time field is not valid (i.e. zero) when
    the state of vcpu is "blocked". (see pt_save_timer function)
    
    The original author (Tim Deegan) of pmtimer_save() must have intended
    that it saves the last scheduled time of the vcpu. Unfortunately it was
    already implied this bug. FYI, there is no other timer mode than
    "delay for missed ticks mode" then.
    
    For consistency with HPET, pmtimer_save() should refer hvm_get_guest_time()
    to update the counter as well as hpet_save() does.
    
    Without this patch, the clock of windows server 2012R2 without HPET
    might leap forward several minutes on live migration.
    
    Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
    
    Retain use of ->arch.hvm_vcpu.guest_time when non-zero. Do the inverse
    adjustment for vHPET.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Tim Deegan <tim@xxxxxxx>
    Reviewed-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
    master commit: 244582a01dcb49fa30083725964a066937cc94f2
    master date: 2015-09-11 16:24:56 +0200
---
 xen/arch/x86/hvm/hpet.c    |    5 ++++-
 xen/arch/x86/hvm/pmtimer.c |   10 ++++++----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c
index 4324b52..97db87d 100644
--- a/xen/arch/x86/hvm/hpet.c
+++ b/xen/arch/x86/hvm/hpet.c
@@ -471,12 +471,15 @@ const struct hvm_mmio_handler hpet_mmio_handler = {
 static int hpet_save(struct domain *d, hvm_domain_context_t *h)
 {
     HPETState *hp = domain_vhpet(d);
+    struct vcpu *v = pt_global_vcpu_target(d);
     int rc;
 
     spin_lock(&hp->lock);
 
     /* Write the proper value into the main counter */
-    hp->hpet.mc64 = hp->mc_offset + guest_time_hpet(hp);
+    hp->hpet.mc64 = hp->mc_offset +
+                    (v->arch.hvm_vcpu.guest_time ?: hvm_get_guest_time(v)) /
+                    STIME_PER_HPET_TICK;
 
     /* Save the HPET registers */
     rc = _hvm_init_entry(h, HVM_SAVE_CODE(HPET), 0, HVM_SAVE_LENGTH(HPET));
diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c
index 6ad2797..0f79e84 100644
--- a/xen/arch/x86/hvm/pmtimer.c
+++ b/xen/arch/x86/hvm/pmtimer.c
@@ -250,10 +250,12 @@ static int pmtimer_save(struct domain *d, 
hvm_domain_context_t *h)
 
     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;
+    /*
+     * Update the counter to the guest's current time.  Make sure it only
+     * goes forwards.
+     */
+    x = (((s->vcpu->arch.hvm_vcpu.guest_time ?: hvm_get_guest_time(s->vcpu)) -
+          s->last_gtime) * s->scale) >> 32;
     if ( x < 1UL<<31 )
         s->pm.tmr_val += x;
     if ( (s->pm.tmr_val & TMR_VAL_MSB) != msb )
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.4

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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