--- src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c.orig	2015-05-07 14:37:15.000000000 -0400
+++ src/VBox/Runtime/r0drv/freebsd/timer-r0drv-freebsd.c	2015-05-12 19:09:22.018982000 -0400
@@ -69,16 +69,23 @@
     PFNRTTIMER              pfnTimer;
     /** User argument. */
     void                   *pvUser;
+#if __FreeBSD_version < 1000029
     /** The timer interval. 0 if one-shot. */
     uint64_t                u64NanoInterval;
     /** The start of the current run.
      * This is used to calculate when the timer ought to fire the next time. */
     uint64_t volatile       u64StartTS;
+    /** The current tick number (since u64StartTS). */
+    uint64_t volatile       iTick;
+#else
+    /** The timer interval. 0 if one-shot. */
+    sbintime_t              iInterval;
     /** The start of the current run.
      * This is used to calculate when the timer ought to fire the next time. */
-    uint64_t volatile       u64NextTS;
-    /** The current tick number (since u64StartTS). */
+    sbintime_t volatile     iStart;
+    /** The current tick number (since iStart). */
     uint64_t volatile       iTick;
+#endif
 } RTTIMER;
 
 
@@ -91,6 +98,10 @@
 
 RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser)
 {
+#if __FreeBSD_version >= 1000029
+    struct timespec ts;
+#endif
+
     *ppTimer = NULL;
 
     /*
@@ -116,8 +127,15 @@
     pTimer->iCpu = fFlags & RTTIMER_FLAGS_CPU_MASK;
     pTimer->pfnTimer = pfnTimer;
     pTimer->pvUser = pvUser;
+#if __FreeBSD_version < 1000029
     pTimer->u64NanoInterval = u64NanoInterval;
     pTimer->u64StartTS = 0;
+#else
+    ts.tv_sec = u64NanoInterval / RT_NS_1SEC_64;
+    ts.tv_nsec = u64NanoInterval % RT_NS_1SEC_64;
+    pTimer->iInterval = tstosbt(ts);
+    pTimer->iStart = 0;
+#endif
     callout_init(&pTimer->Callout, CALLOUT_MPSAFE);
 
     *ppTimer = pTimer;
@@ -159,29 +177,46 @@
 
 RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First)
 {
+#if __FreeBSD_version < 1000029
     struct timeval tv;
+#else
+    struct bintime bt;
+    struct timespec ts;
+#endif
 
     if (!rtTimerIsValid(pTimer))
         return VERR_INVALID_HANDLE;
     if (!pTimer->fSuspended)
         return VERR_TIMER_ACTIVE;
     if (   pTimer->fSpecificCpu
-        && !RTMpIsCpuOnline(pTimer->idCpu))
+        && !RTMpIsCpuOnline(pTimer->iCpu))
         return VERR_CPU_OFFLINE;
 
     /*
      * Calc when it should start firing.
      */
+#if __FreeBSD_version < 1000029
     u64First += RTTimeNanoTS();
+#else
+    ts.tv_sec = u64First / RT_NS_1SEC_64;
+    ts.tv_nsec = u64First % RT_NS_1SEC_64;
+    binuptime(&bt);
+    pTimer->iStart = bttosbt(bt) + tstosbt(ts);
+#endif
 
     pTimer->fSuspended = false;
     pTimer->iTick = 0;
+#if __FreeBSD_version < 1000029
     pTimer->u64StartTS = u64First;
-    pTimer->u64NextTS = u64First;
-
-    tv.tv_sec  =  u64First / 1000000000;
-    tv.tv_usec = (u64First % 1000000000) / 1000;
+    tv.tv_sec  =  u64First / RT_NS_1SEC_64;
+    tv.tv_usec = (u64First % RT_NS_1SEC_64) / RT_NS_1US_64;
     callout_reset(&pTimer->Callout, tvtohz(&tv), rtTimerFreeBSDCallback, pTimer);
+#else
+    if (pTimer->fSpecificCpu)
+        callout_reset_sbt_on(&pTimer->Callout, pTimer->iStart, 0, rtTimerFreeBSDCallback, pTimer, pTimer->iCpu, C_ABSOLUTE);
+    else
+        callout_reset_sbt(&pTimer->Callout, pTimer->iStart, 0, rtTimerFreeBSDCallback, pTimer, C_ABSOLUTE);
+#endif
 
     return VINF_SUCCESS;
 }
@@ -234,22 +269,37 @@
 
     /* calculate and set the next timeout */
     pTimer->iTick++;
+#if __FreeBSD_version < 1000029
     if (!pTimer->u64NanoInterval)
+#else
+    if (!pTimer->iInterval)
+#endif
     {
         pTimer->fSuspended = true;
         callout_stop(&pTimer->Callout);
     }
     else
     {
+#if __FreeBSD_version < 1000029
         struct timeval tv;
         const uint64_t u64NanoTS = RTTimeNanoTS();
-        pTimer->u64NextTS = pTimer->u64StartTS + pTimer->iTick * pTimer->u64NanoInterval;
-        if (pTimer->u64NextTS < u64NanoTS)
-            pTimer->u64NextTS = u64NanoTS + RTTimerGetSystemGranularity() / 2;
-
-        tv.tv_sec = pTimer->u64NextTS / 1000000000;
-        tv.tv_usec = (pTimer->u64NextTS % 1000000000) / 1000;
+        uint64_t u64NextTS = pTimer->iTick * pTimer->u64NanoInterval;
+        if (pTimer->u64StartTS + u64NextTS <= u64NanoTS)
+            u64NextTS = RTTimerGetSystemGranularity() / 2;
+        tv.tv_sec = u64NextTS / RT_NS_1SEC_64;
+        tv.tv_usec = (u64NextTS % RT_NS_1SEC_64) / RT_NS_1US_64;
         callout_reset(&pTimer->Callout, tvtohz(&tv), rtTimerFreeBSDCallback, pTimer);
+#else
+        struct bintime bt;
+        sbintime_t sbt = pTimer->iStart + pTimer->iInterval * pTimer->iTick;
+        binuptime(&bt);
+        if (sbt <= bttosbt(bt))
+            sbt = bttosbt(bt) + SBT_1S / hz / 2;
+        if (pTimer->fSpecificCpu)
+            callout_reset_sbt_on(&pTimer->Callout, sbt, 0, rtTimerFreeBSDCallback, pTimer, pTimer->iCpu, C_ABSOLUTE);
+        else
+            callout_reset_sbt(&pTimer->Callout, sbt, 0, rtTimerFreeBSDCallback, pTimer, C_ABSOLUTE);
+#endif
     }
 
     /* callback */
@@ -263,7 +313,7 @@
 
 RTDECL(uint32_t) RTTimerGetSystemGranularity(void)
 {
-    return 1000000000 / hz; /* ns */
+    return RT_NS_1SEC / hz;
 }
 
 
@@ -283,4 +333,3 @@
 {
     return false;
 }
-
