char opcode[3];
unsigned long eip, rc;
struct vcpu *v = current;
+ const struct domain *currd = v->domain;
eip = regs->rip;
if ( (rc = copy_from_user(opcode, (char *)eip, sizeof(opcode))) != 0 )
if ( memcmp(opcode, "\xf\x1\xf9", sizeof(opcode)) )
return 0;
eip += sizeof(opcode);
- pv_soft_rdtsc(v, regs, 1);
+
+ msr_split(regs, pv_soft_rdtsc(v, regs));
+ regs->rcx = (currd->arch.tsc_mode == TSC_MODE_PVRDTSCP
+ ? currd->arch.incarnation : 0);
+
pv_emul_instruction_done(regs, eip);
return EXCRET_fault_fixed;
}
case X86EMUL_OKAY:
if ( ctxt.tsc & TSC_BASE )
{
- if ( ctxt.tsc & TSC_AUX )
- pv_soft_rdtsc(curr, regs, 1);
- else if ( currd->arch.vtsc )
- pv_soft_rdtsc(curr, regs, 0);
+ if ( currd->arch.vtsc || (ctxt.tsc & TSC_AUX) )
+ {
+ msr_split(regs, pv_soft_rdtsc(curr, regs));
+
+ if ( ctxt.tsc & TSC_AUX )
+ regs->rcx = (currd->arch.tsc_mode == TSC_MODE_PVRDTSCP
+ ? currd->arch.incarnation : 0);
+ }
else
msr_split(regs, rdtsc());
}
return time;
}
-void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs, int rdtscp)
+uint64_t pv_soft_rdtsc(const struct vcpu *v, const struct cpu_user_regs *regs)
{
s_time_t now = get_s_time();
struct domain *d = v->domain;
spin_unlock(&d->arch.vtsc_lock);
- msr_split(regs, gtime_to_gtsc(d, now));
-
- if ( rdtscp )
- regs->rcx =
- (d->arch.tsc_mode == TSC_MODE_PVRDTSCP) ? d->arch.incarnation : 0;
+ return gtime_to_gtsc(d, now);
}
bool clocksource_is_tsc(void)
uint64_t tsc_ticks2ns(uint64_t ticks);
-void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs, int rdtscp);
+uint64_t pv_soft_rdtsc(const struct vcpu *v, const struct cpu_user_regs *regs);
u64 gtime_to_gtsc(struct domain *d, u64 time);
u64 gtsc_to_gtime(struct domain *d, u64 tsc);