Author: sephe
Date: Thu Dec  8 05:37:39 2016
New Revision: 309705
URL: https://svnweb.freebsd.org/changeset/base/309705

Log:
  hyperv/timesync: Support "sent TC" to improve accuracy.
  
  MFC after:    1 week
  Sponsored by: Microsoft
  Differential Revision:        https://reviews.freebsd.org/D8723

Modified:
  head/sys/dev/hyperv/include/hyperv.h
  head/sys/dev/hyperv/utilities/hv_timesync.c
  head/sys/dev/hyperv/utilities/vmbus_icreg.h
  head/sys/dev/hyperv/vmbus/hyperv_reg.h
  head/sys/dev/hyperv/vmbus/hyperv_var.h
  head/sys/dev/hyperv/vmbus/vmbus_et.c

Modified: head/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- head/sys/dev/hyperv/include/hyperv.h        Thu Dec  8 05:15:00 2016        
(r309704)
+++ head/sys/dev/hyperv/include/hyperv.h        Thu Dec  8 05:37:39 2016        
(r309705)
@@ -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_ */

Modified: head/sys/dev/hyperv/utilities/hv_timesync.c
==============================================================================
--- head/sys/dev/hyperv/utilities/hv_timesync.c Thu Dec  8 05:15:00 2016        
(r309704)
+++ head/sys/dev/hyperv/utilities/hv_timesync.c Thu Dec  8 05:37:39 2016        
(r309705)
@@ -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, sam
     &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 *
                    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 *
                        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:

Modified: head/sys/dev/hyperv/utilities/vmbus_icreg.h
==============================================================================
--- head/sys/dev/hyperv/utilities/vmbus_icreg.h Thu Dec  8 05:15:00 2016        
(r309704)
+++ head/sys/dev/hyperv/utilities/vmbus_icreg.h Thu Dec  8 05:37:39 2016        
(r309705)
@@ -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_ */

Modified: head/sys/dev/hyperv/vmbus/hyperv_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hyperv_reg.h      Thu Dec  8 05:15:00 2016        
(r309704)
+++ head/sys/dev/hyperv/vmbus/hyperv_reg.h      Thu Dec  8 05:37:39 2016        
(r309705)
@@ -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 */

Modified: head/sys/dev/hyperv/vmbus/hyperv_var.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hyperv_var.h      Thu Dec  8 05:15:00 2016        
(r309704)
+++ head/sys/dev/hyperv/vmbus/hyperv_var.h      Thu Dec  8 05:37:39 2016        
(r309705)
@@ -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);

Modified: head/sys/dev/hyperv/vmbus/vmbus_et.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_et.c        Thu Dec  8 05:15:00 2016        
(r309704)
+++ head/sys/dev/hyperv/vmbus/vmbus_et.c        Thu Dec  8 05:37:39 2016        
(r309705)
@@ -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>
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to