Index: /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 51685)
+++ /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 51686)
@@ -215,5 +215,5 @@
             /* Enable the TSC-page. */
             RTGCPHYS GCPhysTscPage = MSR_GIM_HV_REF_TSC_GUEST_PFN(uRawValue) << PAGE_SHIFT;
-            int rc = GIMR3HvEnableTscPage(pVM, GCPhysTscPage);
+            int rc = GIMR3HvEnableTscPage(pVM, GCPhysTscPage, false /* fUseThisTscSequence */, 0 /* uTscSequence */);
             if (RT_SUCCESS(rc))
             {
Index: /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 51685)
+++ /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 51686)
@@ -96,5 +96,5 @@
                        | GIM_HV_BASE_FEAT_HYPERCALL_MSRS
                        | GIM_HV_BASE_FEAT_VP_ID_MSR
-                       //| GIM_HV_BASE_FEAT_VIRT_SYS_RESET_MSR
+                       | GIM_HV_BASE_FEAT_VIRT_SYS_RESET_MSR
                        //| GIM_HV_BASE_FEAT_STAT_PAGES_MSR
                        | GIM_HV_BASE_FEAT_PART_REF_TSC_MSR
@@ -248,5 +248,5 @@
      * Unmap MMIO2 pages that the guest may have setup.
      */
-    LogRelFunc(("Resetting Hyper-V MMIO2 regions and MSRs...\n"));
+    LogRel(("GIM: HyperV: Resetting Hyper-V MMIO2 regions and MSRs\n"));
     PGIMHV pHv = &pVM->gim.s.u.Hv;
     for (unsigned i = 0; i < RT_ELEMENTS(pHv->aMmio2Regions); i++)
@@ -313,17 +313,31 @@
 
     /*
-     * Save per-VM MMIO2 regions.
-     */
-    rc = SSMR3PutU32(pSSM, RT_ELEMENTS(pcHv->aMmio2Regions));
-    for (unsigned i = 0; i < RT_ELEMENTS(pcHv->aMmio2Regions); i++)
-    {
-        /* Save the fields necessary to remap the regions upon load.*/
-        PCGIMMMIO2REGION pcRegion = &pcHv->aMmio2Regions[i];
-        rc = SSMR3PutU8(pSSM,     pcRegion->iRegion);           AssertRCReturn(rc, rc);
-        rc = SSMR3PutBool(pSSM,   pcRegion->fRCMapping);        AssertRCReturn(rc, rc);
-        rc = SSMR3PutU32(pSSM,    pcRegion->cbRegion);          AssertRCReturn(rc, rc);
-        rc = SSMR3PutGCPhys(pSSM, pcRegion->GCPhysPage);        AssertRCReturn(rc, rc);
-        rc = SSMR3PutStrZ(pSSM,   pcRegion->szDescription);     AssertRCReturn(rc, rc);
-    }
+     * Save the Hypercall region.
+     */
+    PCGIMMMIO2REGION pcRegion = &pcHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX];
+    rc = SSMR3PutU8(pSSM,     pcRegion->iRegion);           AssertRCReturn(rc, rc);
+    rc = SSMR3PutBool(pSSM,   pcRegion->fRCMapping);        AssertRCReturn(rc, rc);
+    rc = SSMR3PutU32(pSSM,    pcRegion->cbRegion);          AssertRCReturn(rc, rc);
+    rc = SSMR3PutGCPhys(pSSM, pcRegion->GCPhysPage);        AssertRCReturn(rc, rc);
+    rc = SSMR3PutStrZ(pSSM,   pcRegion->szDescription);     AssertRCReturn(rc, rc);
+
+    /*
+     * Save the reference TSC region.
+     */
+    pcRegion = &pcHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX];
+    rc = SSMR3PutU8(pSSM,     pcRegion->iRegion);           AssertRCReturn(rc, rc);
+    rc = SSMR3PutBool(pSSM,   pcRegion->fRCMapping);        AssertRCReturn(rc, rc);
+    rc = SSMR3PutU32(pSSM,    pcRegion->cbRegion);          AssertRCReturn(rc, rc);
+    rc = SSMR3PutGCPhys(pSSM, pcRegion->GCPhysPage);        AssertRCReturn(rc, rc);
+    rc = SSMR3PutStrZ(pSSM,   pcRegion->szDescription);     AssertRCReturn(rc, rc);
+    /* Save the TSC sequence so we can bump it on restore (as the CPU frequency/offset may change). */
+    uint32_t uTscSequence = 0;
+    if (   pcRegion->fMapped
+        && MSR_GIM_HV_REF_TSC_IS_ENABLED(pcHv->u64TscPageMsr))
+    {
+        PCGIMHVREFTSC pcRefTsc = (PCGIMHVREFTSC)pcRegion->pvPageR3;
+        uTscSequence = pcRefTsc->u32TscSequence;
+    }
+    rc = SSMR3PutU32(pSSM,    uTscSequence);                AssertRCReturn(rc, rc);
 
     return VINF_SUCCESS;
@@ -362,34 +376,17 @@
 
     /*
-     * Load per-VM MMIO2 regions.
-     */
-    uint32_t cRegions;
-    rc = SSMR3GetU32(pSSM, &cRegions);
-    if (cRegions != RT_ELEMENTS(pHv->aMmio2Regions))
-    {
-        LogRelFunc(("MMIO2 region array size mismatch. size=%u expected=%u\n", cRegions, RT_ELEMENTS(pHv->aMmio2Regions)));
-        return VERR_SSM_FIELD_INVALID_VALUE;
-    }
-
-    for (unsigned i = 0; i < RT_ELEMENTS(pHv->aMmio2Regions); i++)
-    {
-        /* The regions would have been registered while constructing the GIM device. */
-        PGIMMMIO2REGION pRegion = &pHv->aMmio2Regions[i];
-        rc = SSMR3GetU8(pSSM,     &pRegion->iRegion);           AssertRCReturn(rc, rc);
-        rc = SSMR3GetBool(pSSM,   &pRegion->fRCMapping);        AssertRCReturn(rc, rc);
-        rc = SSMR3GetU32(pSSM,    &pRegion->cbRegion);          AssertRCReturn(rc, rc);
-        rc = SSMR3GetGCPhys(pSSM, &pRegion->GCPhysPage);        AssertRCReturn(rc, rc);
-        rc = SSMR3GetStrZ(pSSM,    pRegion->szDescription, sizeof(pRegion->szDescription));
-        AssertRCReturn(rc, rc);
-    }
-
-    /*
-     * Enable the Hypercall-page.
+     * Load and enable the Hypercall region.
      */
     PGIMMMIO2REGION pRegion = &pHv->aMmio2Regions[GIM_HV_HYPERCALL_PAGE_REGION_IDX];
+    rc = SSMR3GetU8(pSSM,     &pRegion->iRegion);           AssertRCReturn(rc, rc);
+    rc = SSMR3GetBool(pSSM,   &pRegion->fRCMapping);        AssertRCReturn(rc, rc);
+    rc = SSMR3GetU32(pSSM,    &pRegion->cbRegion);          AssertRCReturn(rc, rc);
+    rc = SSMR3GetGCPhys(pSSM, &pRegion->GCPhysPage);        AssertRCReturn(rc, rc);
+    rc = SSMR3GetStrZ(pSSM,    pRegion->szDescription, sizeof(pRegion->szDescription));
+    AssertRCReturn(rc, rc);
     if (MSR_GIM_HV_HYPERCALL_IS_ENABLED(pHv->u64HypercallMsr))
     {
         Assert(pRegion->GCPhysPage != NIL_RTGCPHYS);
-        if (pRegion->fRegistered)
+        if (RT_LIKELY(pRegion->fRegistered))
         {
             rc = GIMR3HvEnableHypercallPage(pVM, pRegion->GCPhysPage);
@@ -403,7 +400,15 @@
 
     /*
-     * Enable the TSC-page.
-     */
+     * Load and enable the reference TSC region.
+     */
+    uint32_t uTscSequence;
     pRegion = &pHv->aMmio2Regions[GIM_HV_REF_TSC_PAGE_REGION_IDX];
+    rc = SSMR3GetU8(pSSM,     &pRegion->iRegion);           AssertRCReturn(rc, rc);
+    rc = SSMR3GetBool(pSSM,   &pRegion->fRCMapping);        AssertRCReturn(rc, rc);
+    rc = SSMR3GetU32(pSSM,    &pRegion->cbRegion);          AssertRCReturn(rc, rc);
+    rc = SSMR3GetGCPhys(pSSM, &pRegion->GCPhysPage);        AssertRCReturn(rc, rc);
+    rc = SSMR3GetStrZ(pSSM,    pRegion->szDescription, sizeof(pRegion->szDescription));
+    rc = SSMR3GetU32(pSSM,    &uTscSequence);               AssertRCReturn(rc, rc);
+    AssertRCReturn(rc, rc);
     if (MSR_GIM_HV_REF_TSC_IS_ENABLED(pHv->u64TscPageMsr))
     {
@@ -411,5 +416,5 @@
         if (pRegion->fRegistered)
         {
-            rc = GIMR3HvEnableTscPage(pVM, pRegion->GCPhysPage);
+            rc = GIMR3HvEnableTscPage(pVM, pRegion->GCPhysPage, true /* fUseThisTscSeq */, uTscSequence);
             if (RT_FAILURE(rc))
                 return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Failed to enable the TSC page. GCPhys=%#RGp rc=%Rrc"),
@@ -428,8 +433,12 @@
  *
  * @returns VBox status code.
- * @param   pVM             Pointer to the VM.
- * @param   GCPhysTscPage   Where to map the TSC page.
- */
-VMMR3_INT_DECL(int) GIMR3HvEnableTscPage(PVM pVM, RTGCPHYS GCPhysTscPage)
+ * @param   pVM                     Pointer to the VM.
+ * @param   GCPhysTscPage           Where to map the TSC page.
+ * @param   fUseThisTscSequence     Whether to set the TSC sequence number to
+ *                                  the one specified in @a uTscSequence.
+ * @param   uTscSequence            The TSC sequence value to use. Ignored if @a
+ *                                  fUseThisTscSequence is false.
+                                                                    */
+VMMR3_INT_DECL(int) GIMR3HvEnableTscPage(PVM pVM, RTGCPHYS GCPhysTscPage, bool fUseThisTscSequence, uint32_t uTscSequence)
 {
     PPDMDEVINSR3    pDevIns = pVM->gim.s.pDevInsR3;
@@ -473,5 +482,11 @@
 
         uint64_t const u64TscKHz = TMCpuTicksPerSecond(pVM) / UINT64_C(1000);
-        pRefTsc->u32TscSequence  = 1;
+        uint32_t       u32TscSeq = 1;
+        if (   fUseThisTscSequence
+            && uTscSequence < UINT32_C(0xfffffffe))
+        {
+            u32TscSeq = uTscSequence + 1;
+        }
+        pRefTsc->u32TscSequence  = u32TscSeq;
         pRefTsc->u64TscScale     = ((INT64_C(10000) << 32) / u64TscKHz) << 32;
 
Index: /trunk/src/VBox/VMM/include/GIMHvInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 51685)
+++ /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 51686)
@@ -511,5 +511,5 @@
 
 VMMR3_INT_DECL(int)             GIMR3HvDisableTscPage(PVM pVM);
-VMMR3_INT_DECL(int)             GIMR3HvEnableTscPage(PVM pVM, RTGCPHYS GCPhysTscPage);
+VMMR3_INT_DECL(int)             GIMR3HvEnableTscPage(PVM pVM, RTGCPHYS GCPhysTscPage, bool fUseThisTscSequence, uint32_t uTscSequence);
 VMMR3_INT_DECL(int)             GIMR3HvDisableHypercallPage(PVM pVM);
 VMMR3_INT_DECL(int)             GIMR3HvEnableHypercallPage(PVM pVM, RTGCPHYS GCPhysHypercallPage);
