aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vpt.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-05-24 09:27:03 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-05-24 09:27:03 +0100
commite1845bbe732b5ad5755f0f3a93fb6ea85919e8a2 (patch)
treefbdbe843c34d11b19ffc3fef6c6304103a1e7bc3 /xen/arch/x86/hvm/vpt.c
parentd0f28d825eafe00591d7b80b8de26e4fd783d924 (diff)
downloadxen-e1845bbe732b5ad5755f0f3a93fb6ea85919e8a2.tar.gz
xen-e1845bbe732b5ad5755f0f3a93fb6ea85919e8a2.tar.bz2
xen-e1845bbe732b5ad5755f0f3a93fb6ea85919e8a2.zip
hvm: Build guest timers on monotonic system time.
Move hvm platform timers from underlying physical CPU TSC to Xen system time and ensure domain-wide monotonicity. TSC on many systems may skew between processors leading to 'time going backwards' messages from some guests. Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/arch/x86/hvm/vpt.c')
-rw-r--r--xen/arch/x86/hvm/vpt.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 832c9042d7..cb62e5e083 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -25,6 +25,36 @@
#define mode_is(d, name) \
((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name)
+void hvm_init_guest_time(struct domain *d)
+{
+ struct pl_time *pl = &d->arch.hvm_domain.pl_time;
+
+ spin_lock_init(&pl->pl_time_lock);
+ pl->stime_offset = -(u64)get_s_time();
+ pl->last_guest_time = 0;
+}
+
+u64 hvm_get_guest_time(struct vcpu *v)
+{
+ struct pl_time *pl = &v->domain->arch.hvm_domain.pl_time;
+ u64 now;
+
+ spin_lock(&pl->pl_time_lock);
+ now = get_s_time() + pl->stime_offset;
+ if ( (int64_t)(now - pl->last_guest_time) >= 0 )
+ pl->last_guest_time = now;
+ else
+ now = pl->last_guest_time;
+ spin_unlock(&pl->pl_time_lock);
+
+ return now + v->arch.hvm_vcpu.stime_offset;
+}
+
+void hvm_set_guest_time(struct vcpu *v, u64 guest_time)
+{
+ v->arch.hvm_vcpu.stime_offset += guest_time - hvm_get_guest_time(v);
+}
+
static int pt_irq_vector(struct periodic_time *pt, enum hvm_intsrc src)
{
struct vcpu *v = pt->vcpu;
@@ -348,7 +378,7 @@ void create_periodic_time(
pt->vcpu = v;
pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu);
pt->irq = irq;
- pt->period_cycles = (u64)period * cpu_khz / 1000000L;
+ pt->period_cycles = (u64)period;
pt->one_shot = one_shot;
pt->scheduled = NOW() + period;
/*