]> xenbits.xensource.com Git - xen.git/commitdiff
This is to align PIT counter with TSC more accurately.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 13 Apr 2006 10:26:01 +0000 (11:26 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 13 Apr 2006 10:26:01 +0000 (11:26 +0100)
Signed-off-by: Eddie Dong <eddie.dong@intel.com>
xen/arch/x86/hvm/intercept.c
xen/arch/x86/hvm/svm/intr.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/svm/vmcb.c
xen/arch/x86/hvm/vmx/io.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/vpit.h

index 77d5527b2c828aa5a9c100e3128dca531ec0bd23..d3883d73470d71ccd88cb82e19326c27124b59b9 100644 (file)
@@ -208,8 +208,9 @@ int register_io_handler(unsigned long addr, unsigned long size,
 
 static void pit_cal_count(struct hvm_virpit *vpit)
 {
-    u64 nsec_delta = (unsigned int)((NOW() - vpit->inject_point));
+    u64 nsec_delta = (unsigned int)((NOW() - vpit->count_point));
 
+    nsec_delta += vpit->count_advance;
     if (nsec_delta > vpit->period)
         HVM_DBG_LOG(DBG_LEVEL_1,
                    "HVM_PIT: long time has passed from last injection!");
index 6d3289e6959a77a535838497d0b356904cb28241..4926ecafab790e6c189ae6acbc736d85e399d7b0 100644 (file)
@@ -79,7 +79,8 @@ interrupt_post_injection(struct vcpu * v, int vector, int type)
         } else {
             vpit->pending_intr_nr--;
         }
-        vpit->inject_point = NOW();
+        vpit->count_advance = 0;
+        vpit->count_point = NOW();
 
         vpit->last_pit_gtime += vpit->period_cycles;
         svm_set_guest_time(v, vpit->last_pit_gtime);
index 8c0f1b00b40a2bdf135439a8bcd4949a3ea19858..0cf9701949ba0d2fce1ff8c2563234b84dde6734 100644 (file)
@@ -679,6 +679,7 @@ static void svm_freeze_time(struct vcpu *v)
     
     if ( vpit->first_injected && !v->domain->arch.hvm_domain.guest_time ) {
         v->domain->arch.hvm_domain.guest_time = svm_get_guest_time(v);
+        vpit->count_advance += (NOW() - vpit->count_point);
         stop_timer(&(vpit->pit_timer));
     }
 }
index 403083d32180285b7b1a80ac8ccab55629b9a485..c76dda5fe06205f9ff29507c7de8f4fa795b1de2 100644 (file)
@@ -485,6 +485,7 @@ void svm_do_resume(struct vcpu *v)
     if ( vpit->first_injected ) {
         if ( v->domain->arch.hvm_domain.guest_time ) {
             svm_set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+            vpit->count_point = NOW();
             v->domain->arch.hvm_domain.guest_time = 0;
         }
         pickup_deactive_ticks(vpit);
index 18c793f843c7cdfcaaf9d19fc54100647375c693..d9d65b1a0c056284d2aa114c2fdbdea566b70007 100644 (file)
@@ -84,7 +84,8 @@ interrupt_post_injection(struct vcpu * v, int vector, int type)
         } else {
             vpit->pending_intr_nr--;
         }
-        vpit->inject_point = NOW();
+        vpit->count_advance = 0;
+        vpit->count_point = NOW();
 
         vpit->last_pit_gtime += vpit->period_cycles;
         set_guest_time(v, vpit->last_pit_gtime);
@@ -208,6 +209,7 @@ void vmx_do_resume(struct vcpu *v)
     /* pick up the elapsed PIT ticks and re-enable pit_timer */
     if ( vpit->first_injected ) {
         if ( v->domain->arch.hvm_domain.guest_time ) {
+            vpit->count_point = NOW();
             set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
             v->domain->arch.hvm_domain.guest_time = 0;
         }
index 059b188f91596a10f594739331e4f7481d74c20b..bfa00d6798ba675e8d5e5861fa988b55582a8af7 100644 (file)
@@ -362,6 +362,7 @@ static void vmx_freeze_time(struct vcpu *v)
     
     if ( vpit->first_injected && !v->domain->arch.hvm_domain.guest_time ) {
         v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
+        vpit->count_advance += (NOW() - vpit->count_point);
         stop_timer(&(vpit->pit_timer));
     }
 }
index 0b955b470c23c59e31599878713ca48402a1ad3b..848277cf7391460e86c530fd3bff07287a5df1ed 100644 (file)
@@ -38,7 +38,8 @@
 struct hvm_virpit {
     /* for simulation of counter 0 in mode 2 */
     u64 period_cycles;          /* pit frequency in cpu cycles */
-    s_time_t inject_point;      /* the time inject virt intr */
+    s_time_t count_advance;     /* accumulated count advance since last fire */
+    s_time_t count_point;        /* last point accumulating count advance */
     s_time_t scheduled;         /* scheduled timer interrupt */
     struct timer pit_timer;     /* periodic timer for mode 2*/
     unsigned int channel;       /* the pit channel, counter 0~2 */