# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 56a775219c88491d46395e8c34d72241c9a27253
# Parent 760f9149dbaa8e07445f1e1227380a92b4205a3a
This patch fix HVM/VMX time resolution issue that cause IA32E complain
"loss tick" occationally and APIC time calibration issue.
Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx>
Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>
diff -r 760f9149dbaa -r 56a775219c88 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Sun Mar 19 16:10:20 2006
+++ b/xen/arch/x86/hvm/intercept.c Sun Mar 19 17:52:20 2006
@@ -338,10 +338,10 @@
static __inline__ void missed_ticks(struct hvm_virpit*vpit)
{
- int missed_ticks;
+ int missed_ticks;
missed_ticks = (NOW() - vpit->scheduled)/(s_time_t) vpit->period;
- if ( missed_ticks > 0 ) {
+ if ( missed_ticks++ >= 0 ) {
vpit->pending_intr_nr += missed_ticks;
vpit->scheduled += missed_ticks * vpit->period;
}
@@ -355,22 +355,16 @@
/* pick up missed timer tick */
missed_ticks(vpit);
-
- vpit->pending_intr_nr++;
if ( test_bit(_VCPUF_running, &v->vcpu_flags) ) {
- vpit->scheduled += vpit->period;
set_timer(&vpit->pit_timer, vpit->scheduled);
}
}
+/* pick up missed timer ticks at deactive time */
void pickup_deactive_ticks(struct hvm_virpit *vpit)
{
-
if ( !active_timer(&(vpit->pit_timer)) ) {
- /* pick up missed timer tick */
missed_ticks(vpit);
-
- vpit->scheduled += vpit->period;
set_timer(&vpit->pit_timer, vpit->scheduled);
}
}
diff -r 760f9149dbaa -r 56a775219c88 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Sun Mar 19 16:10:20 2006
+++ b/xen/arch/x86/hvm/vmx/io.c Sun Mar 19 17:52:20 2006
@@ -40,20 +40,33 @@
#define BSP_CPU(v) (!(v->vcpu_id))
-void vmx_set_tsc_shift(struct vcpu *v, struct hvm_virpit *vpit)
-{
- u64 drift;
-
- if ( vpit->first_injected )
- drift = vpit->period_cycles * vpit->pending_intr_nr;
- else
- drift = 0;
- vpit->shift = v->arch.hvm_vmx.tsc_offset - drift;
- __vmwrite(TSC_OFFSET, vpit->shift);
-
+static inline
+void __set_tsc_offset(u64 offset)
+{
+ __vmwrite(TSC_OFFSET, offset);
#if defined (__i386__)
- __vmwrite(TSC_OFFSET_HIGH, ((vpit->shift)>> 32));
+ __vmwrite(TSC_OFFSET_HIGH, offset >> 32);
#endif
+}
+
+u64 get_guest_time(struct vcpu *v)
+{
+ struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ u64 host_tsc;
+
+ rdtscll(host_tsc);
+ return host_tsc + vpit->cache_tsc_offset;
+}
+
+void set_guest_time(struct vcpu *v, u64 gtime)
+{
+ struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
+ u64 host_tsc;
+
+ rdtscll(host_tsc);
+
+ vpit->cache_tsc_offset = gtime - host_tsc;
+ __set_tsc_offset(vpit->cache_tsc_offset);
}
static inline void
@@ -64,6 +77,7 @@
if ( is_pit_irq(v, vector, type) ) {
if ( !vpit->first_injected ) {
vpit->pending_intr_nr = 0;
+ vpit->last_pit_gtime = get_guest_time(v);
vpit->scheduled = NOW() + vpit->period;
set_timer(&vpit->pit_timer, vpit->scheduled);
vpit->first_injected = 1;
@@ -71,7 +85,9 @@
vpit->pending_intr_nr--;
}
vpit->inject_point = NOW();
- vmx_set_tsc_shift (v, vpit);
+
+ vpit->last_pit_gtime += vpit->period;
+ set_guest_time(v, vpit->last_pit_gtime);
}
switch(type)
@@ -189,14 +205,15 @@
vmx_stts();
+ /* pick up the elapsed PIT ticks and re-enable pit_timer */
+ if ( vpit->first_injected) {
+ set_guest_time(v, v->domain->arch.hvm_domain.guest_time);
+ pickup_deactive_ticks(vpit);
+ }
+
if ( test_bit(iopacket_port(v), &d->shared_info->evtchn_pending[0]) ||
test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
hvm_wait_io();
-
- /* pick up the elapsed PIT ticks and re-enable pit_timer */
- if ( vpit->first_injected )
- pickup_deactive_ticks(vpit);
- vmx_set_tsc_shift(v, vpit);
/* We can't resume the guest if we're waiting on I/O */
ASSERT(!test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags));
diff -r 760f9149dbaa -r 56a775219c88 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Sun Mar 19 16:10:20 2006
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Sun Mar 19 17:52:20 2006
@@ -195,7 +195,6 @@
/* Update CR3, GDT, LDT, TR */
unsigned int error = 0;
unsigned long cr0, cr4;
- u64 host_tsc;
if (v->vcpu_id == 0)
hvm_setup_platform(v->domain);
@@ -250,9 +249,7 @@
v->arch.hvm_vmx.launch_cpu = smp_processor_id();
/* init guest tsc to start from 0 */
- rdtscll(host_tsc);
- v->arch.hvm_vmx.tsc_offset = 0 - host_tsc;
- vmx_set_tsc_shift(v, &v->domain->arch.hvm_domain.vpit);
+ set_guest_time(v, 0);
}
/*
diff -r 760f9149dbaa -r 56a775219c88 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Sun Mar 19 16:10:20 2006
+++ b/xen/arch/x86/hvm/vmx/vmx.c Sun Mar 19 17:52:20 2006
@@ -354,8 +354,18 @@
#endif /* __i386__ */
+static void vmx_freeze_time(struct vcpu *v)
+{
+ struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
+
+ v->domain->arch.hvm_domain.guest_time = get_guest_time(v);
+ if ( vpit->first_injected )
+ stop_timer(&(vpit->pit_timer));
+}
+
static void vmx_ctxt_switch_from(struct vcpu *v)
{
+ vmx_freeze_time(v);
vmx_save_segments(v);
vmx_load_msrs();
}
@@ -1707,7 +1717,7 @@
rdtscll(msr_content);
vpit = &(v->domain->arch.hvm_domain.vpit);
- msr_content += vpit->shift;
+ msr_content += vpit->cache_tsc_offset;
break;
}
case MSR_IA32_SYSENTER_CS:
@@ -1751,22 +1761,8 @@
switch (regs->ecx) {
case MSR_IA32_TIME_STAMP_COUNTER:
- {
- struct hvm_virpit *vpit;
- u64 host_tsc, drift;
-
- rdtscll(host_tsc);
- vpit = &(v->domain->arch.hvm_domain.vpit);
- drift = v->arch.hvm_vmx.tsc_offset - vpit->shift;
- vpit->shift = msr_content - host_tsc;
- v->arch.hvm_vmx.tsc_offset = vpit->shift + drift;
- __vmwrite(TSC_OFFSET, vpit->shift);
-
-#if defined (__i386__)
- __vmwrite(TSC_OFFSET_HIGH, ((vpit->shift)>>32));
-#endif
- break;
- }
+ set_guest_time(v, msr_content);
+ break;
case MSR_IA32_SYSENTER_CS:
__vmwrite(GUEST_SYSENTER_CS, msr_content);
break;
diff -r 760f9149dbaa -r 56a775219c88 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h Sun Mar 19 16:10:20 2006
+++ b/xen/include/asm-x86/hvm/domain.h Sun Mar 19 17:52:20 2006
@@ -37,6 +37,7 @@
unsigned int pae_enabled;
struct hvm_virpit vpit;
+ u64 guest_time;
struct hvm_virpic vpic;
struct hvm_vioapic vioapic;
struct hvm_io_handler io_handler;
diff -r 760f9149dbaa -r 56a775219c88 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h Sun Mar 19 16:10:20 2006
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Sun Mar 19 17:52:20 2006
@@ -77,7 +77,6 @@
unsigned long cpu_based_exec_control;
struct vmx_msr_state msr_content;
void *io_bitmap_a, *io_bitmap_b;
- u64 tsc_offset;
struct timer hlt_timer; /* hlt ins emulation wakeup timer */
};
diff -r 760f9149dbaa -r 56a775219c88 xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Sun Mar 19 16:10:20 2006
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Sun Mar 19 17:52:20 2006
@@ -30,10 +30,11 @@
extern void vmx_asm_do_resume(void);
extern void vmx_asm_do_launch(void);
extern void vmx_intr_assist(void);
-extern void vmx_set_tsc_shift(struct vcpu *, struct hvm_virpit *);
extern void vmx_migrate_timers(struct vcpu *v);
extern void arch_vmx_do_launch(struct vcpu *);
extern void arch_vmx_do_resume(struct vcpu *);
+extern void set_guest_time(struct vcpu *v, u64 gtime);
+extern u64 get_guest_time(struct vcpu *v);
extern unsigned int cpu_rev;
diff -r 760f9149dbaa -r 56a775219c88 xen/include/asm-x86/hvm/vpit.h
--- a/xen/include/asm-x86/hvm/vpit.h Sun Mar 19 16:10:20 2006
+++ b/xen/include/asm-x86/hvm/vpit.h Sun Mar 19 17:52:20 2006
@@ -38,7 +38,6 @@
struct hvm_virpit {
/* for simulation of counter 0 in mode 2 */
u64 period_cycles; /* pit frequency in cpu cycles */
- u64 shift; /* save the value of offset - drift */
s_time_t inject_point; /* the time inject virt intr */
s_time_t scheduled; /* scheduled timer interrupt */
struct timer pit_timer; /* periodic timer for mode 2*/
@@ -46,6 +45,8 @@
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 */
+ s64 cache_tsc_offset; /* cache of VMCS TSC_OFFSET offset */
+ u64 last_pit_gtime; /* guest time when last pit is injected */
/* virtual PIT state for handle related I/O */
int read_state;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|