summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2017-01-05 06:19:07 +0000
committersephe <sephe@FreeBSD.org>2017-01-05 06:19:07 +0000
commitf0e951e4dc53424aeffd634d9ab9446d1d41b8a7 (patch)
treeafcc0898ff9b6f1da5b65d8af9fb9a33a2d3bc23 /sys/dev/hyperv
parent12eb396a5a6fe9fa25ecc805e8d7d8b3224c884a (diff)
downloadFreeBSD-src-f0e951e4dc53424aeffd634d9ab9446d1d41b8a7.zip
FreeBSD-src-f0e951e4dc53424aeffd634d9ab9446d1d41b8a7.tar.gz
MFC 309705
hyperv/timesync: Support "sent TC" to improve accuracy. Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8723
Diffstat (limited to 'sys/dev/hyperv')
-rw-r--r--sys/dev/hyperv/include/hyperv.h19
-rw-r--r--sys/dev/hyperv/utilities/hv_timesync.c21
-rw-r--r--sys/dev/hyperv/utilities/vmbus_icreg.h7
-rw-r--r--sys/dev/hyperv/vmbus/hyperv_reg.h12
-rw-r--r--sys/dev/hyperv/vmbus/hyperv_var.h7
-rw-r--r--sys/dev/hyperv/vmbus/vmbus_et.c1
6 files changed, 38 insertions, 29 deletions
diff --git a/sys/dev/hyperv/include/hyperv.h b/sys/dev/hyperv/include/hyperv.h
index 73b8d81..c5e7dec 100644
--- a/sys/dev/hyperv/include/hyperv.h
+++ b/sys/dev/hyperv/include/hyperv.h
@@ -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_ */
diff --git a/sys/dev/hyperv/utilities/hv_timesync.c b/sys/dev/hyperv/utilities/hv_timesync.c
index 5bd51b0..4d166b0 100644
--- a/sys/dev/hyperv/utilities/hv_timesync.c
+++ b/sys/dev/hyperv/utilities/hv_timesync.c
@@ -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;
+
+ if (VMBUS_TIMESYNC_DORTT(sc))
+ rtt = rdmsr(MSR_HV_TIME_REF_COUNT) - sent_tc;
- hv_ns = (hvtime - VMBUS_ICMSG_TS_BASE) * VMBUS_ICMSG_TS_FACTOR;
+ 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:
diff --git a/sys/dev/hyperv/utilities/vmbus_icreg.h b/sys/dev/hyperv/utilities/vmbus_icreg.h
index 3435962..fea74f0 100644
--- a/sys/dev/hyperv/utilities/vmbus_icreg.h
+++ b/sys/dev/hyperv/utilities/vmbus_icreg.h
@@ -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_ */
diff --git a/sys/dev/hyperv/vmbus/hyperv_reg.h b/sys/dev/hyperv/vmbus/hyperv_reg.h
index 9796958..4fb1228 100644
--- a/sys/dev/hyperv/vmbus/hyperv_reg.h
+++ b/sys/dev/hyperv/vmbus/hyperv_reg.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 */
diff --git a/sys/dev/hyperv/vmbus/hyperv_var.h b/sys/dev/hyperv/vmbus/hyperv_var.h
index ce51e9d..f620e4f 100644
--- a/sys/dev/hyperv/vmbus/hyperv_var.h
+++ b/sys/dev/hyperv/vmbus/hyperv_var.h
@@ -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);
diff --git a/sys/dev/hyperv/vmbus/vmbus_et.c b/sys/dev/hyperv/vmbus/vmbus_et.c
index 9e217ec..feb639c 100644
--- a/sys/dev/hyperv/vmbus/vmbus_et.c
+++ b/sys/dev/hyperv/vmbus/vmbus_et.c
@@ -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>
OpenPOWER on IntegriCloud