Mailing List Archive

Improve VMX guest TSC accuracy when guests are
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# Node ID 37e19db6ecc338b86eca0b382aa8e2810078171a
# Parent 08c0861679ce5d90d027fac81388de87809bbec8
Improve VMX guest TSC accuracy when guests are
competing for the same physical CPU.

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

diff -r 08c0861679ce -r 37e19db6ecc3 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Thu Dec 8 08:57:55 2005
+++ b/xen/arch/x86/vmx.c Thu Dec 8 14:13:38 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 08c0861679ce -r 37e19db6ecc3 xen/arch/x86/vmx_intercept.c
--- a/xen/arch/x86/vmx_intercept.c Thu Dec 8 08:57:55 2005
+++ b/xen/arch/x86/vmx_intercept.c Thu Dec 8 14:13:38 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 08c0861679ce -r 37e19db6ecc3 xen/arch/x86/vmx_io.c
--- a/xen/arch/x86/vmx_io.c Thu Dec 8 08:57:55 2005
+++ b/xen/arch/x86/vmx_io.c Thu Dec 8 14:13:38 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 08c0861679ce -r 37e19db6ecc3 xen/arch/x86/vmx_vmcs.c
--- a/xen/arch/x86/vmx_vmcs.c Thu Dec 8 08:57:55 2005
+++ b/xen/arch/x86/vmx_vmcs.c Thu Dec 8 14:13:38 2005
@@ -290,6 +290,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);
@@ -337,6 +338,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);
}

/*
@@ -366,7 +371,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 08c0861679ce -r 37e19db6ecc3 xen/include/asm-x86/vmx_vpit.h
--- a/xen/include/asm-x86/vmx_vpit.h Thu Dec 8 08:57:55 2005
+++ b/xen/include/asm-x86/vmx_vpit.h Thu Dec 8 14:13:38 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_ */

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