hyperv/timesync: Support "sent TC" to improve accuracy.
MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8723
This commit is contained in:
parent
092f1602f5
commit
6091327a9b
@ -36,6 +36,23 @@
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#define MSR_HV_TIME_REF_COUNT 0x40000020
|
||||
|
||||
#define CPUID_HV_MSR_TIME_REFCNT 0x0002 /* MSR_HV_TIME_REF_COUNT */
|
||||
#define CPUID_HV_MSR_SYNIC 0x0004 /* MSRs for SynIC */
|
||||
#define CPUID_HV_MSR_SYNTIMER 0x0008 /* MSRs for SynTimer */
|
||||
#define CPUID_HV_MSR_APIC 0x0010 /* MSR_HV_{EOI,ICR,TPR} */
|
||||
#define CPUID_HV_MSR_HYPERCALL 0x0020 /* MSR_HV_GUEST_OS_ID
|
||||
* MSR_HV_HYPERCALL */
|
||||
#define CPUID_HV_MSR_VP_INDEX 0x0040 /* MSR_HV_VP_INDEX */
|
||||
#define CPUID_HV_MSR_GUEST_IDLE 0x0400 /* MSR_HV_GUEST_IDLE */
|
||||
|
||||
#ifndef NANOSEC
|
||||
#define NANOSEC 1000000000ULL
|
||||
#endif
|
||||
#define HYPERV_TIMER_NS_FACTOR 100ULL
|
||||
#define HYPERV_TIMER_FREQ (NANOSEC / HYPERV_TIMER_NS_FACTOR)
|
||||
|
||||
struct hyperv_guid {
|
||||
uint8_t hv_guid[16];
|
||||
} __packed;
|
||||
@ -44,4 +61,6 @@ struct hyperv_guid {
|
||||
|
||||
int hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
|
||||
|
||||
extern u_int hyperv_features; /* CPUID_HV_MSR_ */
|
||||
|
||||
#endif /* _HYPERV_H_ */
|
||||
|
@ -46,10 +46,14 @@ __FBSDID("$FreeBSD$");
|
||||
#define VMBUS_TIMESYNC_FWVER \
|
||||
VMBUS_IC_VERSION(VMBUS_TIMESYNC_FWVER_MAJOR, 0)
|
||||
|
||||
#define VMBUS_TIMESYNC_MSGVER_MAJOR 3
|
||||
#define VMBUS_TIMESYNC_MSGVER_MAJOR 4
|
||||
#define VMBUS_TIMESYNC_MSGVER \
|
||||
VMBUS_IC_VERSION(VMBUS_TIMESYNC_MSGVER_MAJOR, 0)
|
||||
|
||||
#define VMBUS_TIMESYNC_DORTT(sc) \
|
||||
((sc)->ic_msgver >= VMBUS_IC_VERSION(4, 0) && \
|
||||
(hyperv_features & CPUID_HV_MSR_TIME_REFCNT))
|
||||
|
||||
static const struct vmbus_ic_desc vmbus_timesync_descs[] = {
|
||||
{
|
||||
.ic_guid = { .hv_guid = {
|
||||
@ -81,12 +85,16 @@ SYSCTL_INT(_hw_hvtimesync, OID_AUTO, sample_verbose, CTLFLAG_RWTUN,
|
||||
&vmbus_ts_sample_verbose, 0, "Increase sample request verbosity.");
|
||||
|
||||
static void
|
||||
vmbus_timesync(struct hv_util_sc *sc, uint64_t hvtime, uint8_t tsflags)
|
||||
vmbus_timesync(struct hv_util_sc *sc, uint64_t hvtime, uint64_t sent_tc,
|
||||
uint8_t tsflags)
|
||||
{
|
||||
struct timespec vm_ts;
|
||||
uint64_t hv_ns, vm_ns;
|
||||
uint64_t hv_ns, vm_ns, rtt = 0;
|
||||
|
||||
hv_ns = (hvtime - VMBUS_ICMSG_TS_BASE) * VMBUS_ICMSG_TS_FACTOR;
|
||||
if (VMBUS_TIMESYNC_DORTT(sc))
|
||||
rtt = rdmsr(MSR_HV_TIME_REF_COUNT) - sent_tc;
|
||||
|
||||
hv_ns = (hvtime - VMBUS_ICMSG_TS_BASE + rtt) * HYPERV_TIMER_NS_FACTOR;
|
||||
nanotime(&vm_ts);
|
||||
vm_ns = (vm_ts.tv_sec * NANOSEC) + vm_ts.tv_nsec;
|
||||
|
||||
@ -174,6 +182,8 @@ vmbus_timesync_cb(struct vmbus_channel *chan, void *xsc)
|
||||
VMBUS_TIMESYNC_FWVER, VMBUS_TIMESYNC_MSGVER);
|
||||
if (error)
|
||||
return;
|
||||
if (VMBUS_TIMESYNC_DORTT(sc))
|
||||
device_printf(sc->ic_dev, "RTT\n");
|
||||
break;
|
||||
|
||||
case VMBUS_ICMSG_TYPE_TIMESYNC:
|
||||
@ -183,7 +193,8 @@ vmbus_timesync_cb(struct vmbus_channel *chan, void *xsc)
|
||||
return;
|
||||
}
|
||||
msg = data;
|
||||
vmbus_timesync(sc, msg->ic_hvtime, msg->ic_tsflags);
|
||||
vmbus_timesync(sc, msg->ic_hvtime, msg->ic_sent_tc,
|
||||
msg->ic_tsflags);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -114,18 +114,13 @@ struct vmbus_icmsg_timesync {
|
||||
struct vmbus_icmsg_hdr ic_hdr;
|
||||
uint64_t ic_hvtime;
|
||||
uint64_t ic_vmtime;
|
||||
uint64_t ic_rtt;
|
||||
uint64_t ic_sent_tc;
|
||||
uint8_t ic_tsflags; /* VMBUS_ICMSG_TS_FLAG_ */
|
||||
} __packed;
|
||||
|
||||
#define VMBUS_ICMSG_TS_FLAG_SYNC 0x01
|
||||
#define VMBUS_ICMSG_TS_FLAG_SAMPLE 0x02
|
||||
|
||||
/* XXX consolidate w/ hyperv */
|
||||
#define VMBUS_ICMSG_TS_BASE 116444736000000000ULL
|
||||
#define VMBUS_ICMSG_TS_FACTOR 100ULL
|
||||
#ifndef NANOSEC
|
||||
#define NANOSEC 1000000000ULL
|
||||
#endif
|
||||
|
||||
#endif /* !_VMBUS_ICREG_H_ */
|
||||
|
@ -57,8 +57,6 @@
|
||||
|
||||
#define MSR_HV_VP_INDEX 0x40000002
|
||||
|
||||
#define MSR_HV_TIME_REF_COUNT 0x40000020
|
||||
|
||||
#define MSR_HV_SCONTROL 0x40000080
|
||||
#define MSR_HV_SCTRL_ENABLE 0x0001ULL
|
||||
#define MSR_HV_SCTRL_RSVD_MASK 0xfffffffffffffffeULL
|
||||
@ -106,15 +104,7 @@
|
||||
#define CPUID_LEAF_HV_IDENTITY 0x40000002
|
||||
|
||||
#define CPUID_LEAF_HV_FEATURES 0x40000003
|
||||
/* EAX: features */
|
||||
#define CPUID_HV_MSR_TIME_REFCNT 0x0002 /* MSR_HV_TIME_REF_COUNT */
|
||||
#define CPUID_HV_MSR_SYNIC 0x0004 /* MSRs for SynIC */
|
||||
#define CPUID_HV_MSR_SYNTIMER 0x0008 /* MSRs for SynTimer */
|
||||
#define CPUID_HV_MSR_APIC 0x0010 /* MSR_HV_{EOI,ICR,TPR} */
|
||||
#define CPUID_HV_MSR_HYPERCALL 0x0020 /* MSR_HV_GUEST_OS_ID
|
||||
* MSR_HV_HYPERCALL */
|
||||
#define CPUID_HV_MSR_VP_INDEX 0x0040 /* MSR_HV_VP_INDEX */
|
||||
#define CPUID_HV_MSR_GUEST_IDLE 0x0400 /* MSR_HV_GUEST_IDLE */
|
||||
/* EAX: features include/hyperv.h CPUID_HV_MSR */
|
||||
/* ECX: power management features */
|
||||
#define CPUPM_HV_CSTATE_MASK 0x000f /* deepest C-state */
|
||||
#define CPUPM_HV_C3_HPET 0x0010 /* C3 requires HPET */
|
||||
|
@ -29,13 +29,6 @@
|
||||
#ifndef _HYPERV_VAR_H_
|
||||
#define _HYPERV_VAR_H_
|
||||
|
||||
#ifndef NANOSEC
|
||||
#define NANOSEC 1000000000ULL
|
||||
#endif
|
||||
#define HYPERV_TIMER_NS_FACTOR 100ULL
|
||||
#define HYPERV_TIMER_FREQ (NANOSEC / HYPERV_TIMER_NS_FACTOR)
|
||||
|
||||
extern u_int hyperv_features;
|
||||
extern u_int hyperv_recommends;
|
||||
|
||||
uint64_t hypercall_post_message(bus_addr_t msg_paddr);
|
||||
|
@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/timeet.h>
|
||||
|
||||
#include <dev/hyperv/include/hyperv.h>
|
||||
#include <dev/hyperv/vmbus/hyperv_reg.h>
|
||||
#include <dev/hyperv/vmbus/hyperv_var.h>
|
||||
#include <dev/hyperv/vmbus/vmbus_var.h>
|
||||
|
Loading…
Reference in New Issue
Block a user