Index: /trunk/src/VBox/VMM/PGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGM.cpp	(revision 24076)
+++ /trunk/src/VBox/VMM/PGM.cpp	(revision 24077)
@@ -2999,4 +2999,7 @@
 VMMR3DECL(int) PGMR3ChangeMode(PVM pVM, PVMCPU pVCpu, PGMMODE enmGuestMode)
 {
+    bool fIsOldGuestPagingMode64Bits = (pVCpu->pgm.s.enmGuestMode >= PGMMODE_AMD64);
+    bool fIsNewGuestPagingMode64Bits = (enmGuestMode >= PGMMODE_AMD64);
+
     Log(("PGMR3ChangeMode: Guest mode: %s -> %s\n", PGMGetModeName(pVCpu->pgm.s.enmGuestMode), PGMGetModeName(enmGuestMode)));
     STAM_REL_COUNTER_INC(&pVCpu->pgm.s.cGuestModeChanges);
@@ -3023,6 +3026,14 @@
      * Exit old mode(s).
      */
+#if HC_ARCH_BITS == 32
+    /* The nested shadow paging mode for AMD-V does change when running 64 bits guests on 32 bits hosts; typically PAE <-> AMD64 */
+    const bool fForceShwEnterExit = (    fIsOldGuestPagingMode64Bits != fIsNewGuestPagingMode64Bits 
+                                     &&  enmShadowMode == PGMMODE_NESTED);
+#else
+    const bool fForceShwEnterExit = false;
+#endif
     /* shadow */
-    if (enmShadowMode != pVCpu->pgm.s.enmShadowMode)
+    if (    enmShadowMode != pVCpu->pgm.s.enmShadowMode
+        ||  fForceShwEnterExit)
     {
         LogFlow(("PGMR3ChangeMode: Shadow mode: %s -> %s\n",  PGMGetModeName(pVCpu->pgm.s.enmShadowMode), PGMGetModeName(enmShadowMode)));
@@ -3060,5 +3071,6 @@
      * Enter new shadow mode (if changed).
      */
-    if (enmShadowMode != pVCpu->pgm.s.enmShadowMode)
+    if (    enmShadowMode != pVCpu->pgm.s.enmShadowMode
+        ||  fForceShwEnterExit)
     {
         int rc;
@@ -3067,19 +3079,19 @@
         {
             case PGMMODE_32_BIT:
-                rc = PGM_SHW_NAME_32BIT(Enter)(pVCpu);
+                rc = PGM_SHW_NAME_32BIT(Enter)(pVCpu, false);
                 break;
             case PGMMODE_PAE:
             case PGMMODE_PAE_NX:
-                rc = PGM_SHW_NAME_PAE(Enter)(pVCpu);
+                rc = PGM_SHW_NAME_PAE(Enter)(pVCpu, false);
                 break;
             case PGMMODE_AMD64:
             case PGMMODE_AMD64_NX:
-                rc = PGM_SHW_NAME_AMD64(Enter)(pVCpu);
+                rc = PGM_SHW_NAME_AMD64(Enter)(pVCpu, fIsNewGuestPagingMode64Bits);
                 break;
             case PGMMODE_NESTED:
-                rc = PGM_SHW_NAME_NESTED(Enter)(pVCpu);
+                rc = PGM_SHW_NAME_NESTED(Enter)(pVCpu, fIsNewGuestPagingMode64Bits);
                 break;
             case PGMMODE_EPT:
-                rc = PGM_SHW_NAME_EPT(Enter)(pVCpu);
+                rc = PGM_SHW_NAME_EPT(Enter)(pVCpu, fIsNewGuestPagingMode64Bits);
                 break;
             case PGMMODE_REAL:
Index: /trunk/src/VBox/VMM/PGMShw.h
===================================================================
--- /trunk/src/VBox/VMM/PGMShw.h	(revision 24076)
+++ /trunk/src/VBox/VMM/PGMShw.h	(revision 24077)
@@ -121,5 +121,5 @@
 /* r3 */
 PGM_SHW_DECL(int, InitData)(PVM pVM, PPGMMODEDATA pModeData, bool fResolveGCAndR0);
-PGM_SHW_DECL(int, Enter)(PVMCPU pVCpu);
+PGM_SHW_DECL(int, Enter)(PVMCPU pVCpu, bool fIs64BitsPagingMode);
 PGM_SHW_DECL(int, Relocate)(PVMCPU pVCpu, RTGCPTR offDelta);
 PGM_SHW_DECL(int, Exit)(PVMCPU pVCpu);
@@ -175,10 +175,17 @@
  *
  * @returns VBox status code.
- * @param   pVCpu       The VMCPU to operate on.
- */
-PGM_SHW_DECL(int, Enter)(PVMCPU pVCpu)
+ * @param   pVCpu                   The VMCPU to operate on.
+ * @param   fIs64BitsPagingMode     New shadow paging mode is for 64 bits? (only relevant for 64 bits guests on a 32 bits AMD-V nested paging host)
+ */
+PGM_SHW_DECL(int, Enter)(PVMCPU pVCpu, bool fIs64BitsPagingMode)
 {
 #if PGM_SHW_TYPE == PGM_TYPE_NESTED || PGM_SHW_TYPE == PGM_TYPE_EPT
+
+# if PGM_SHW_TYPE == PGM_TYPE_NESTED && HC_ARCH_BITS == 32
+    /* Must distinguish between 32 and 64 bits guest paging modes as we'll use a different shadow paging root/mode in both cases. */
+    RTGCPHYS     GCPhysCR3 = (fIs64BitsPagingMode) ? RT_BIT_64(63) : RT_BIT_64(62);
+# else
     RTGCPHYS     GCPhysCR3 = RT_BIT_64(63);
+# endif
     PPGMPOOLPAGE pNewShwPageCR3;
     PVM          pVM       = pVCpu->pVMR3;
@@ -188,4 +195,6 @@
     Assert(!pVCpu->pgm.s.pShwPageCR3R3);
 
+    pgmLock(pVM);
+
     int rc = pgmPoolAlloc(pVM, GCPhysCR3, PGMPOOLKIND_ROOT_NESTED, PGMPOOL_IDX_NESTED_ROOT, GCPhysCR3 >> PAGE_SHIFT, &pNewShwPageCR3, true /* lock page */);
     AssertFatalRC(rc);
@@ -197,4 +206,6 @@
     pVCpu->pgm.s.pShwPageCR3RC = MMHyperCCToRC(pVM, pVCpu->pgm.s.pShwPageCR3R3);
     pVCpu->pgm.s.pShwPageCR3R0 = MMHyperCCToR0(pVM, pVCpu->pgm.s.pShwPageCR3R3);
+
+    pgmUnlock(pVM);
 
     Log(("Enter nested shadow paging mode: root %RHv phys %RHp\n", pVCpu->pgm.s.pShwPageCR3R3, pVCpu->pgm.s.CTX_SUFF(pShwPageCR3)->Core.Key));
@@ -235,4 +246,6 @@
 
         Assert(pVCpu->pgm.s.iShwUser == PGMPOOL_IDX_NESTED_ROOT);
+
+        pgmLock(pVM);
 
         /* Mark the page as unlocked; allow flushing again. */
@@ -246,4 +259,6 @@
         pVCpu->pgm.s.iShwUserTable = 0;
 
+        pgmUnlock(pVM);
+
         Log(("Leave nested shadow paging mode\n"));
     }
