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

[Xen-devel] fix multiple-VM guest TSC issues.


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: "Dong, Eddie" <eddie.dong@xxxxxxxxx>
  • Date: Wed, 7 Dec 2005 14:54:43 +0800
  • Delivery-date: Wed, 07 Dec 2005 06:55:47 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: AcX6+xotJzmbDe1pTsGFx4iIXIZ0WA==
  • Thread-topic: [Xen-devel] fix multiple-VM guest TSC issues.

Keir:
        This patch is to fix the guest time accurate issue when multiple
VMX guests run on same LP.
Thx,eddie



Signed-off-by:  Eddie Dong <eddie.dong@xxxxxxxxx>





diff -r 213175bc9a26 -r f4a0a4dc2d6d xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c        Mon Dec  5 08:06:18 2005
+++ b/xen/arch/x86/vmx.c        Mon Dec  5 10:09:14 2005
@@ -108,7 +108,7 @@
     destroy_vmcs(&v->arch.arch_vmx);
     free_monitor_pagetable(v);
     vpit = &v->domain->arch.vmx_platform.vmx_pit;
-    if ( vpit->ticking && active_ac_timer(&(vpit->pit_timer)) )
+    if ( active_ac_timer(&(vpit->pit_timer)) )
         rem_ac_timer(&vpit->pit_timer);
     if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) ) {
         rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
diff -r 213175bc9a26 -r f4a0a4dc2d6d xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c      Mon Dec  5 08:06:18 2005
+++ b/xen/arch/x86/vmx_intercept.c      Mon Dec  5 10:09:14 2005
@@ -387,7 +387,6 @@
         }
         else {
             init_ac_timer(&vpit->pit_timer, pit_timer_fn, v,
v->processor);
-            vpit->ticking = 1;
         }
 
         /* init count for this channel */
diff -r 213175bc9a26 -r f4a0a4dc2d6d xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c     Mon Dec  5 08:06:18 2005
+++ b/xen/arch/x86/vmx_io.c     Mon Dec  5 10:09:14 2005
@@ -793,29 +793,39 @@
     return __fls(pintr[0]);
 }
 
+void set_tsc_shift(struct vcpu *v,struct vmx_virpit *vpit)
+{
+    u64   drift;
+
+    if ( vpit->first_injected )
+        drift = vpit->period_cycles * vpit->pending_intr_nr;
+    else 
+        drift = 0;
+    drift = v->arch.arch_vmx.tsc_offset - drift;
+    __vmwrite(TSC_OFFSET, drift);
+
+#if defined (__i386__)
+    __vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
+#endif
+}
+
 #define BSP_CPU(v)    (!(v->vcpu_id))
 static inline void
 interrupt_post_injection(struct vcpu * v, int vector, int type)
 {
     struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
-    u64    drift;
 
     if ( is_pit_irq(v, vector, type) ) {
         if ( !vpit->first_injected ) {
+            vpit->pending_intr_nr = 0;
+            vpit->scheduled = NOW() + vpit->period;
+            set_ac_timer(&vpit->pit_timer, vpit->scheduled);
             vpit->first_injected = 1;
-            vpit->pending_intr_nr = 0;
         } else {
             vpit->pending_intr_nr--;
         }
         vpit->inject_point = NOW();
-        drift = vpit->period_cycles * vpit->pending_intr_nr;
-        drift = v->arch.arch_vmx.tsc_offset - drift;
-        __vmwrite(TSC_OFFSET, drift);
-
-#if defined (__i386__)
-        __vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
-#endif
-
+        set_tsc_shift (v, vpit);
     }
 
     switch(type)
@@ -982,8 +992,10 @@
             vmx_wait_io();
     }
     /* pick up the elapsed PIT ticks and re-enable pit_timer */
-    if ( vpit->ticking )
+    if ( vpit->first_injected ) {
         pickup_deactive_ticks(vpit);
+    }
+    set_tsc_shift(v,vpit);
 
     /* We can't resume the guest if we're waiting on I/O */
     ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags));
diff -r 213175bc9a26 -r f4a0a4dc2d6d xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c   Mon Dec  5 08:06:18 2005
+++ b/xen/arch/x86/vmx_vmcs.c   Mon Dec  5 10:09:14 2005
@@ -287,6 +287,7 @@
 /* Update CR3, GDT, LDT, TR */
     unsigned int  error = 0;
     unsigned long cr0, cr4;
+    u64     host_tsc;
 
     if (v->vcpu_id == 0)
         vmx_setup_platform(v->domain);
@@ -334,6 +335,10 @@
     __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
 
     v->arch.schedule_tail = arch_vmx_do_resume;
+    /* init guest tsc to start from 0 */
+    rdtscll(host_tsc);
+    v->arch.arch_vmx.tsc_offset = 0 - host_tsc;
+    set_tsc_shift (v, &v->domain->arch.vmx_platform.vmx_pit);
 }
 
 /*
@@ -363,7 +368,6 @@
     error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, 0);
 
     /* TSC */
-    error |= __vmwrite(TSC_OFFSET, 0);
     error |= __vmwrite(CR3_TARGET_COUNT, 0);
 
     /* Guest Selectors */
diff -r 213175bc9a26 -r f4a0a4dc2d6d xen/include/asm-x86/vmx_vpit.h
--- a/xen/include/asm-x86/vmx_vpit.h    Mon Dec  5 08:06:18 2005
+++ b/xen/include/asm-x86/vmx_vpit.h    Mon Dec  5 10:09:14 2005
@@ -27,7 +27,6 @@
     unsigned int pending_intr_nr; /* the couner for pending timer
interrupts */
     u32 period;                /* pit frequency in ns */
     int first_injected;                 /* flag to prevent shadow
window */
-    int ticking;    /* indicating it is ticking */
 
     /* virtual PIT state for handle related I/O */
     int read_state;
@@ -51,5 +50,6 @@
     else
         return -1;
 }
+extern void set_tsc_shift(struct vcpu *v,struct vmx_virpit *vpit);
 
 #endif /* _VMX_VIRPIT_H_ */

Attachment: tsc_n2.patch
Description: tsc_n2.patch

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

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