INIT_PAGE_LIST_HEAD(&d->arch.relmem_list);
spin_lock_init(&d->arch.e820_lock);
- spin_lock_init(&d->arch.vtsc_lock);
/* Minimal initialisation for the idle domain. */
if ( unlikely(is_idle_domain(d)) )
uint64_t pv_soft_rdtsc(const struct vcpu *v, const struct cpu_user_regs *regs)
{
- s_time_t now = get_s_time();
+ s_time_t old, new, now = get_s_time();
struct domain *d = v->domain;
- spin_lock(&d->arch.vtsc_lock);
-
- if ( (int64_t)(now - d->arch.vtsc_last) > 0 )
- d->arch.vtsc_last = now;
- else
- now = ++d->arch.vtsc_last;
-
- spin_unlock(&d->arch.vtsc_lock);
+ do {
+ old = d->arch.vtsc_last;
+ new = now > d->arch.vtsc_last ? now : old + 1;
+ } while ( cmpxchg(&d->arch.vtsc_last, old, new) != old );
- return gtime_to_gtsc(d, now);
+ return gtime_to_gtsc(d, new);
}
bool clocksource_is_tsc(void)
int tsc_mode; /* see include/asm-x86/time.h */
bool_t vtsc; /* tsc is emulated (may change after migrate) */
s_time_t vtsc_last; /* previous TSC value (guarantee monotonicity) */
- spinlock_t vtsc_lock;
uint64_t vtsc_offset; /* adjustment for save/restore/migrate */
uint32_t tsc_khz; /* cached guest khz for certain emulated or
hardware TSC scaling cases */