Index: /trunk/src/VBox/Devices/PC/DevHPET.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 79685)
+++ /trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 79686)
@@ -75,4 +75,19 @@
  */
 #define FS_PER_NS                   1000000
+
+/**
+ * Femtoseconds in a day. Still fits within int64_t.
+ */
+#define FS_PER_DAY                  (1000000LL * 60 * 60 * 24 * FS_PER_NS)
+
+/**
+ * Number of HPET ticks in 100 years, ICH9 frequency.
+ */
+#define HPET_TICKS_IN_100YR_ICH9    (FS_PER_DAY / HPET_CLK_PERIOD_ICH9 * 365 * 100)
+
+/**
+ * Number of HPET ticks in 100 years, made-up PIIX frequency.
+ */
+#define HPET_TICKS_IN_100YR_PIIX    (FS_PER_DAY / HPET_CLK_PERIOD_PIIX * 365 * 100)
 
 /** @name Interrupt type
@@ -385,5 +400,5 @@
 
 
-static void hpetProgramTimer(HPETTIMER *pHpetTimer)
+static void hpetProgramTimer(HPET *pThis, HPETTIMER *pHpetTimer)
 {
     /* no wrapping on new timers */
@@ -420,6 +435,14 @@
 #endif
 
-    Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff)));
-    TMTimerSetNano(pHpetTimer->CTX_SUFF(pTimer), hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff));
+    uint64_t u64TickLimit = pThis->fIch9 ? HPET_TICKS_IN_100YR_ICH9 : HPET_TICKS_IN_100YR_PIIX;
+    if (u64Diff <= u64TickLimit)
+    {
+        Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff)));
+        TMTimerSetNano(pHpetTimer->CTX_SUFF(pTimer), hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff));
+    }
+    else
+    {
+        LogRelMax(10, ("HPET: Not scheduling an interrupt more than 100 years in the future.\n"));
+    }
     hpetTimerSetFrequencyHint(pHpetTimer->CTX_SUFF(pHpet), pHpetTimer);
 }
@@ -568,5 +591,5 @@
 
             if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
-                hpetProgramTimer(pHpetTimer);
+                hpetProgramTimer(pThis, pHpetTimer);
             DEVHPET_UNLOCK_BOTH(pThis);
             break;
@@ -588,5 +611,5 @@
 
                 if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
-                    hpetProgramTimer(pHpetTimer);
+                    hpetProgramTimer(pThis, pHpetTimer);
             }
             DEVHPET_UNLOCK_BOTH(pThis);
@@ -755,9 +778,19 @@
 /** @todo Only get the time stamp once when reprogramming? */
                 /* Enable main counter and interrupt generation. */
-                pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter)
-                                     - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
+                uint64_t u64TickLimit = pThis->fIch9 ? HPET_TICKS_IN_100YR_ICH9 : HPET_TICKS_IN_100YR_PIIX;
+                if (pThis->u64HpetCounter <= u64TickLimit)
+                {
+                    pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter)
+                                         - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
+                }
+                else
+                {
+                    LogRelMax(10, ("HPET: Counter set more than 100 years in the future, reducing.\n"));
+                    pThis->u64HpetOffset = 1000000LL * 60 * 60 * 24 * 365 * 100
+                                         - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
+                }
                 for (uint32_t i = 0; i < cTimers; i++)
                     if (pThis->aTimers[i].u64Cmp != hpetInvalidValue(&pThis->aTimers[i]))
-                        hpetProgramTimer(&pThis->aTimers[i]);
+                        hpetProgramTimer(pThis, &pThis->aTimers[i]);
             }
             else if (hpetBitJustCleared(iOldValue, u32NewValue, HPET_CFG_ENABLE))
@@ -1038,6 +1071,14 @@
             u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick);
 
-            Log4(("HPET: periodic: next in %llu\n", hpetTicksToNs(pThis, u64Diff)));
-            TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));
+            uint64_t u64TickLimit = pThis->fIch9 ? HPET_TICKS_IN_100YR_ICH9 : HPET_TICKS_IN_100YR_PIIX;
+            if (u64Diff <= u64TickLimit)
+            {
+                Log4(("HPET: periodic: next in %llu\n", hpetTicksToNs(pThis, u64Diff)));
+                TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));
+            }
+            else
+            {
+                LogRelMax(10, ("HPET: Not scheduling periodic interrupt more than 100 years in the future.\n"));
+            }
         }
     }
@@ -1268,5 +1309,5 @@
         /* We can do all IRQs */
         uint32_t u32RoutingCap = 0xffffffff;
-        pHpetTimer->u64Config |= ((uint64_t)u32RoutingCap) << 32;
+        pHpetTimer->u64Config |= ((uint64_t)u32RoutingCap) << HPET_TN_INT_ROUTE_CAP_SHIFT;
         pHpetTimer->u64Period  = 0;
         pHpetTimer->u8Wrap     = 0;
