Index: trunk/src/VBox/VMM/SELM.cpp
===================================================================
--- trunk/src/VBox/VMM/SELM.cpp	(revision 67)
+++ trunk/src/VBox/VMM/SELM.cpp	(revision 68)
@@ -66,5 +66,5 @@
 
 /** SELM saved state version. */
-#define SELM_SAVED_STATE_VERSION    4
+#define SELM_SAVED_STATE_VERSION    5
 
 /*******************************************************************************
@@ -139,4 +139,5 @@
 
     pVM->selm.s.fDisableMonitoring = false;
+    pVM->selm.s.fSyncTSSRing0Stack = false;
 
     /*
@@ -506,4 +507,6 @@
     pVM->selm.s.cbMonitoredGuestTss = 0;
 
+    pVM->selm.s.fSyncTSSRing0Stack = false;
+
     /*
      * Default action when entering raw mode for the first time
@@ -604,5 +607,6 @@
     PSELM pSelm = &pVM->selm.s;
 
-    SSMR3PutUInt(pSSM, pSelm->fDisableMonitoring);
+    SSMR3PutBool(pSSM, pSelm->fDisableMonitoring);
+    SSMR3PutBool(pSSM, pSelm->fSyncTSSRing0Stack);
     SSMR3PutSel(pSSM, pSelm->SelCS);
     SSMR3PutSel(pSSM, pSelm->SelDS);
@@ -641,5 +645,8 @@
 
     /* Get the monitoring flag. */
-    SSMR3GetUInt(pSSM, &pVM->selm.s.fDisableMonitoring);
+    SSMR3GetBool(pSSM, &pVM->selm.s.fDisableMonitoring);
+
+    /* Get the TSS state flag. */
+    SSMR3GetBool(pSSM, &pVM->selm.s.fSyncTSSRing0Stack);
 
     /*
@@ -1447,29 +1454,7 @@
             }
 
-            /* Update the ring 0 stack selector and base address */
-            /* feeling very lazy; reading too much */
-            VBOXTSS tss;
-            rc = PGMPhysReadGCPtr(pVM, &tss, GCPtrTss, sizeof(VBOXTSS));
-            if (VBOX_FAILURE(rc))
-            {
-                /// @todo this might not be as fatal as it seems!
-                AssertReleaseMsgFailed(("Unable to read TSS structure at %08X\n", GCPtrTss));
-                STAM_PROFILE_STOP(&pVM->selm.s.StatTSSSync, a);
-                return VERR_NOT_IMPLEMENTED;
-            }
-#ifdef DEBUG
-            uint32_t ssr0, espr0;
-
-            SELMGetRing1Stack(pVM, &ssr0, &espr0);
-            ssr0 &= ~1;
-
-            if (ssr0 != tss.ss0 || espr0 != tss.esp0)
-            {
-                Log(("SELMR3SyncTSS: Updating TSS ring 0 stack to %04X:%08X\n", tss.ss0, tss.esp0));
-            }
-Log(("offIoBitmap=%#x\n", tss.offIoBitmap));
-#endif
-            /* Update our TSS structure for the guest's ring 1 stack */
-            SELMSetRing1Stack(pVM, tss.ss0 | 1, tss.esp0);
+            /** @note the ring 0 stack selector and base address are updated on demand (as it should) */
+            pVM->selm.s.fSyncTSSRing0Stack = true;
+
             VM_FF_CLEAR(pVM, VM_FF_SELM_SYNC_TSS);
         }
@@ -1670,31 +1655,34 @@
     }
 
-    RTGCPTR     pGuestTSS = pVM->selm.s.GCPtrGuestTss;
-    uint32_t    ESPR0;
-    int rc = PGMPhysReadGCPtr(pVM, &ESPR0, pGuestTSS + RT_OFFSETOF(VBOXTSS, esp0), sizeof(ESPR0));
-    if (VBOX_SUCCESS(rc))
-    {
-        RTSEL SelSS0;
-        rc = PGMPhysReadGCPtr(pVM, &SelSS0, pGuestTSS + RT_OFFSETOF(VBOXTSS, ss0), sizeof(SelSS0));
+    if (!pVM->selm.s.fSyncTSSRing0Stack)
+    {
+        RTGCPTR     pGuestTSS = pVM->selm.s.GCPtrGuestTss;
+        uint32_t    ESPR0;
+        int rc = PGMPhysReadGCPtr(pVM, &ESPR0, pGuestTSS + RT_OFFSETOF(VBOXTSS, esp0), sizeof(ESPR0));
         if (VBOX_SUCCESS(rc))
         {
-            if (    ESPR0 == pVM->selm.s.Tss.esp1
-                &&  SelSS0 == (pVM->selm.s.Tss.ss1 & ~1))
-                return true;
-
-            RTGCPHYS GCPhys;
-            uint64_t fFlags;
-
-            rc = PGMGstGetPage(pVM, pGuestTSS, &fFlags, &GCPhys);
-            AssertRC(rc);
-            AssertMsgFailed(("TSS out of sync!! (%04X:%08X vs %04X:%08X (guest)) Tss=%VGv Phys=%VGp\n",
-                             (pVM->selm.s.Tss.ss1 & ~1), pVM->selm.s.Tss.esp1, SelSS0, ESPR0, pGuestTSS, GCPhys));
+            RTSEL SelSS0;
+            rc = PGMPhysReadGCPtr(pVM, &SelSS0, pGuestTSS + RT_OFFSETOF(VBOXTSS, ss0), sizeof(SelSS0));
+            if (VBOX_SUCCESS(rc))
+            {
+                if (    ESPR0 == pVM->selm.s.Tss.esp1
+                    &&  SelSS0 == (pVM->selm.s.Tss.ss1 & ~1))
+                    return true;
+
+                RTGCPHYS GCPhys;
+                uint64_t fFlags;
+
+                rc = PGMGstGetPage(pVM, pGuestTSS, &fFlags, &GCPhys);
+                AssertRC(rc);
+                AssertMsgFailed(("TSS out of sync!! (%04X:%08X vs %04X:%08X (guest)) Tss=%VGv Phys=%VGp\n",
+                                 (pVM->selm.s.Tss.ss1 & ~1), pVM->selm.s.Tss.esp1, SelSS0, ESPR0, pGuestTSS, GCPhys));
+            }
+            else
+                AssertRC(rc);
         }
         else
-            AssertRC(rc);
-    }
-    else
-        /* Happens during early Windows XP boot when it is switching page tables. */
-        Assert(rc == VINF_SUCCESS || ((rc == VERR_PAGE_TABLE_NOT_PRESENT || rc == VERR_PAGE_NOT_PRESENT) && !(CPUMGetGuestEFlags(pVM) & X86_EFL_IF)));
+            /* Happens during early Windows XP boot when it is switching page tables. */
+            Assert(rc == VINF_SUCCESS || ((rc == VERR_PAGE_TABLE_NOT_PRESENT || rc == VERR_PAGE_NOT_PRESENT) && !(CPUMGetGuestEFlags(pVM) & X86_EFL_IF)));
+    }
     return false;
 #else
Index: trunk/src/VBox/VMM/SELMInternal.h
===================================================================
--- trunk/src/VBox/VMM/SELMInternal.h	(revision 67)
+++ trunk/src/VBox/VMM/SELMInternal.h	(revision 68)
@@ -124,8 +124,11 @@
 
     /** Indicates that the Guest GDT access handler have been registered. */
-    RTUINT                  fGDTRangeRegistered; /** @todo r=bird: use bool when we mean bool. Just keep in mind that it's a 1 byte byte. */
+    bool                    fGDTRangeRegistered;
 
     /** Indicates whether LDT/GDT/TSS monitoring and syncing is disabled. */
-    RTUINT                  fDisableMonitoring;
+    bool                    fDisableMonitoring;
+
+    /** Indicates whether the TSS stack selector & base address need to be refreshed.  */
+    bool                    fSyncTSSRing0Stack;
 
     /** SELMR3UpdateFromCPUM() profiling. */
Index: trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/SELMAll.cpp	(revision 67)
+++ trunk/src/VBox/VMM/VMMAll/SELMAll.cpp	(revision 68)
@@ -35,4 +35,5 @@
 #include <iprt/assert.h>
 #include <VBox/log.h>
+#include <VBox/pgm.h>
 
 
@@ -499,4 +500,43 @@
 SELMDECL(void) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, uint32_t *pEsp)
 {
+
+    if (pVM->selm.s.fSyncTSSRing0Stack)
+    {
+        GCPTRTYPE(uint8_t *)GCPtrTss = (GCPTRTYPE(uint8_t *))pVM->selm.s.GCPtrGuestTss;
+        int     rc;
+        VBOXTSS tss;
+
+        Assert(pVM->selm.s.GCPtrGuestTss && pVM->selm.s.cbMonitoredGuestTss);
+
+#ifdef IN_GC
+        rc  = MMGCRamRead(pVM, &tss.ss0,  GCPtrTss + RT_OFFSETOF(VBOXTSS, ss0), sizeof(tss.ss0));
+        rc |= MMGCRamRead(pVM, &tss.esp0, GCPtrTss + RT_OFFSETOF(VBOXTSS, esp0), sizeof(tss.esp0));
+  #ifdef DEBUG
+        rc |= MMGCRamRead(pVM, &tss.offIoBitmap, GCPtrTss + RT_OFFSETOF(VBOXTSS, offIoBitmap), sizeof(tss.offIoBitmap));
+  #endif
+#else /* IN_GC */
+        /* Reading too much. Could be cheaper than two seperate calls though. */
+        rc = PGMPhysReadGCPtr(pVM, &tss, GCPtrTss, sizeof(VBOXTSS));
+#endif /* IN_GC */
+        if (VBOX_FAILURE(rc))
+        {
+            AssertReleaseMsgFailed(("Unable to read TSS structure at %08X\n", GCPtrTss));
+            return;
+        }
+#ifdef DEBUG
+        uint32_t ssr0  = pVM->selm.s.Tss.ss1;
+        uint32_t espr0 = pVM->selm.s.Tss.esp1;
+        ssr0 &= ~1;
+
+        if (ssr0 != tss.ss0 || espr0 != tss.esp0)
+            Log(("SELMGetRing1Stack: Updating TSS ring 0 stack to %04X:%08X\n", tss.ss0, tss.esp0));
+
+        Log(("offIoBitmap=%#x\n", tss.offIoBitmap));
+#endif
+        /* Update our TSS structure for the guest's ring 1 stack */
+        SELMSetRing1Stack(pVM, tss.ss0 | 1, tss.esp0);
+        pVM->selm.s.fSyncTSSRing0Stack = false;
+    }
+
     *pSS  = pVM->selm.s.Tss.ss1;
     *pEsp = pVM->selm.s.Tss.esp1;
