The documentation for the Linux pvclock is pretty sparse but I am pretty sure we want to use a monotonic base for ti_system_time. We also have a function for converting a timespec into a 64-bit count of nanoseconds we can use.
We may as well also use rdtsc_lfence() to ensure consistent behavior. ... this is still not quite right because the VM expects the pvclock to have a fixed frequency, but we have no interface to reading a raw timestamp. Something to add in the future, maybe. Index: vmm.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/vmm.c,v retrieving revision 1.284 diff -u -p -r1.284 vmm.c --- vmm.c 18 May 2021 00:05:20 -0000 1.284 +++ vmm.c 2 Jun 2021 00:57:31 -0000 @@ -7294,8 +7294,8 @@ vmm_init_pvclock(struct vcpu *vcpu, padd int vmm_update_pvclock(struct vcpu *vcpu) { + struct timespec now; struct pvclock_time_info *pvclock_ti; - struct timespec tv; struct vm *vm = vcpu->vc_parent; paddr_t pvclock_hpa, pvclock_gpa; @@ -7309,10 +7309,9 @@ vmm_update_pvclock(struct vcpu *vcpu) pvclock_ti->ti_version = (++vcpu->vc_pvclock_version << 1) | 0x1; - pvclock_ti->ti_tsc_timestamp = rdtsc(); - nanotime(&tv); - pvclock_ti->ti_system_time = - tv.tv_sec * 1000000000L + tv.tv_nsec; + pvclock_ti->ti_tsc_timestamp = rdtsc_lfence(); + nanouptime(&now); + pvclock_ti->ti_system_time = TIMESPEC_TO_NSEC(&now); pvclock_ti->ti_tsc_shift = 12; pvclock_ti->ti_tsc_to_system_mul = vcpu->vc_pvclock_system_tsc_mul;