diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-05-24 09:27:03 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-05-24 09:27:03 +0100 |
commit | e1845bbe732b5ad5755f0f3a93fb6ea85919e8a2 (patch) | |
tree | fbdbe843c34d11b19ffc3fef6c6304103a1e7bc3 /xen/arch/x86/hvm/vpt.c | |
parent | d0f28d825eafe00591d7b80b8de26e4fd783d924 (diff) | |
download | xen-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.c | 32 |
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; /* |