Index: trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 31080)
+++ trunk/src/VBox/VMM/VMMAll/PGMAll.cpp	(revision 31081)
@@ -71,6 +71,6 @@
 DECLINLINE(int) pgmShwGetPaePoolPagePD(PPGMCPU pPGM, RTGCPTR GCPtr, PPGMPOOLPAGE *ppShwPde);
 #ifndef IN_RC
-static int      pgmShwSyncLongModePDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PCX86PML4E pGstPml4e, PCX86PDPE pGstPdpe, PX86PDPAE *ppPD);
-static int      pgmShwGetEPTPDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PEPTPDPT *ppPdpt, PEPTPD *ppPD);
+static int pgmShwSyncLongModePDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, X86PGPAEUINT uGstPml4e, X86PGPAEUINT uGstPdpe, PX86PDPAE *ppPD);
+static int pgmShwGetEPTPDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PEPTPDPT *ppPdpt, PEPTPD *ppPD);
 #endif
 
@@ -914,8 +914,8 @@
  * @param   pVCpu       The VMCPU handle.
  * @param   GCPtr       The address.
- * @param   pGstPdpe    Guest PDPT entry
+ * @param   uGstPdpe    Guest PDPT entry.
  * @param   ppPD        Receives address of page directory
  */
-int pgmShwSyncPaePDPtr(PVMCPU pVCpu, RTGCPTR GCPtr, PCX86PDPE pGstPdpe, PX86PDPAE *ppPD)
+int pgmShwSyncPaePDPtr(PVMCPU pVCpu, RTGCPTR GCPtr, X86PGPAEUINT uGstPdpe, PX86PDPAE *ppPD)
 {
     const unsigned iPdPt    = (GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_PAE;
@@ -935,6 +935,4 @@
         RTGCPTR64   GCPdPt;
         PGMPOOLKIND enmKind;
-        Assert(pGstPdpe);
-        X86PDPE     GstPdpe = *pGstPdpe;
 
 # if defined(IN_RC)
@@ -953,5 +951,5 @@
             if (CPUMGetGuestCR4(pVCpu) & X86_CR4_PAE)
             {
-                if (!GstPdpe.n.u1Present)
+                if (!(uGstPdpe & X86_PDPE_P))
                 {
                     /* PD not present; guest must reload CR3 to change it.
@@ -960,11 +958,11 @@
                     Assert(!HWACCMIsEnabled(pVM));
 
-                    GCPdPt  = GstPdpe.u & X86_PDPE_PG_MASK;
+                    GCPdPt  = uGstPdpe & X86_PDPE_PG_MASK;
                     enmKind = PGMPOOLKIND_PAE_PD_PHYS;
-                    GstPdpe.n.u1Present = 1;
+                    uGstPdpe |= X86_PDPE_P;
                 }
                 else
                 {
-                    GCPdPt  = GstPdpe.u & X86_PDPE_PG_MASK;
+                    GCPdPt  = uGstPdpe & X86_PDPE_PG_MASK;
                     enmKind = PGMPOOLKIND_PAE_PD_FOR_PAE_PD;
                 }
@@ -983,5 +981,5 @@
         /* The PD was cached or created; hook it up now. */
         pPdpe->u |= pShwPage->Core.Key
-                 | (GstPdpe.u & ~(X86_PDPE_PG_MASK | X86_PDPE_AVL_MASK | X86_PDPE_PCD | X86_PDPE_PWT));
+                 | (uGstPdpe & ~(X86_PDPE_PG_MASK | X86_PDPE_AVL_MASK | X86_PDPE_PCD | X86_PDPE_PWT));
 
 # if defined(IN_RC)
@@ -1052,9 +1050,9 @@
  * @param   pVCpu       VMCPU handle.
  * @param   GCPtr       The address.
- * @param   pGstPml4e   Guest PML4 entry
- * @param   pGstPdpe    Guest PDPT entry
+ * @param   uGstPml4e   Guest PML4 entry
+ * @param   uGstPdpe    Guest PDPT entry
  * @param   ppPD        Receives address of page directory
  */
-static int pgmShwSyncLongModePDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PCX86PML4E pGstPml4e, PCX86PDPE pGstPdpe, PX86PDPAE *ppPD)
+static int pgmShwSyncLongModePDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, X86PGPAEUINT uGstPml4e, X86PGPAEUINT uGstPdpe, PX86PDPAE *ppPD)
 {
     PPGMCPU        pPGM          = &pVCpu->pgm.s;
@@ -1086,7 +1084,5 @@
         else
         {
-            Assert(pGstPml4e && pGstPdpe);
-
-            GCPml4  = pGstPml4e->u & X86_PML4E_PG_MASK;
+            GCPml4  = uGstPml4e & X86_PML4E_PG_MASK;
             enmKind = PGMPOOLKIND_64BIT_PDPT_FOR_64BIT_PDPT;
         }
@@ -1105,5 +1101,5 @@
     /* The PDPT was cached or created; hook it up now. */
     pPml4e->u |= pShwPage->Core.Key
-              | (pGstPml4e->u & ~(X86_PML4E_PG_MASK | X86_PML4E_AVL_MASK | X86_PML4E_PCD | X86_PML4E_PWT));
+              | (uGstPml4e & ~(X86_PML4E_PG_MASK | X86_PML4E_AVL_MASK | X86_PML4E_PCD | X86_PML4E_PWT));
 
     const unsigned iPdPt = (GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64;
@@ -1126,7 +1122,5 @@
         else
         {
-            Assert(pGstPdpe);
-
-            GCPdPt  = pGstPdpe->u & X86_PDPE_PG_MASK;
+            GCPdPt  = uGstPdpe & X86_PDPE_PG_MASK;
             enmKind = PGMPOOLKIND_64BIT_PD_FOR_64BIT_PD;
         }
@@ -1145,5 +1139,5 @@
     /* The PD was cached or created; hook it up now. */
     pPdpe->u |= pShwPage->Core.Key
-             | (pGstPdpe->u & ~(X86_PDPE_PG_MASK | X86_PDPE_AVL_MASK | X86_PDPE_PCD | X86_PDPE_PWT));
+             | (uGstPdpe & ~(X86_PDPE_PG_MASK | X86_PDPE_AVL_MASK | X86_PDPE_PCD | X86_PDPE_PWT));
 
     *ppPD = (PX86PDPAE)PGMPOOL_PAGE_2_PTR(pVM, pShwPage);
Index: trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 31080)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllBth.h	(revision 31081)
@@ -36,5 +36,5 @@
 PGM_BTH_DECL(int, SyncPage)(PVMCPU pVCpu, GSTPDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uErr);
 PGM_BTH_DECL(int, CheckPageFault)(PVMCPU pVCpu, uint32_t uErr, PGSTPDE pPdeSrc, RTGCPTR GCPtrPage);
-PGM_BTH_DECL(int, CheckDirtyPageFault)(PVMCPU pVCpu, uint32_t uErr, PSHWPDE pPdeDst, PGSTPDE pPdeSrc, RTGCPTR GCPtrPage);
+PGM_BTH_DECL(int, CheckDirtyPageFault)(PVMCPU pVCpu, uint32_t uErr, PSHWPDE pPdeDst, GSTPDE const *pPdeSrc, RTGCPTR GCPtrPage);
 PGM_BTH_DECL(int, SyncPT)(PVMCPU pVCpu, unsigned iPD, PGSTPD pPDSrc, RTGCPTR GCPtrPage);
 PGM_BTH_DECL(int, VerifyAccessSyncPage)(PVMCPU pVCpu, RTGCPTR Addr, unsigned fPage, unsigned uErr);
@@ -73,6 +73,63 @@
 #endif
 
+/* enables the new code. */
+#define PGM_WITH_GST_WALK
 
 #ifndef IN_RING3
+
+#ifdef PGM_WITH_GST_WALK
+# if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+/**
+ * Deal with a guest page fault.
+ *
+ * @returns Strict VBox status code.
+ * @retval  VINF_EM_RAW_GUEST_TRAP
+ * @retval  VINF_EM_RAW_EMULATE_INSTR
+ *
+ * @param   pVCpu           The current CPU.
+ * @param   pGstWalk        The guest page table walk result.
+ * @param   uErr            The error code.
+ */
+PGM_BTH_DECL(VBOXSTRICTRC, Trap0eHandlerGuestFault)(PVMCPU pVCpu, PGSTPTWALK pGstWalk, RTGCUINT uErr)
+{
+#  if !defined(PGM_WITHOUT_MAPPINGS) && (PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE)
+    /*
+     * Check for write conflicts with our hypervisor mapping.
+     *
+     * If the  guest happens to access a non-present page, where our hypervisor
+     * is currently mapped, then we'll create a #PF storm in the guest.
+     */
+    if (    (uErr & (X86_TRAP_PF_P | X86_TRAP_PF_RW)) == (X86_TRAP_PF_P | X86_TRAP_PF_RW)
+        &&  MMHyperIsInsideArea(pVCpu->CTX_SUFF(pVM), pGstWalk->Core.GCPtr))
+    {
+        /* Force a CR3 sync to check for conflicts and emulate the instruction. */
+        VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3);
+        STAM_STATS({ pVCpu->pgm.s.CTX_SUFF(pStatTrap0eAttribution) = &pVCpu->pgm.s.StatRZTrap0eTime2GuestTrap; });
+        return VINF_EM_RAW_EMULATE_INSTR;
+    }
+#  endif
+
+    /*
+     * Calc the error code for the guest trap.
+     */
+    uint32_t uNewErr = GST_IS_NX_ACTIVE(pVCpu)
+                     ? uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US | X86_TRAP_PF_ID)
+                     : uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US);
+    if (pGstWalk->Core.fBadPhysAddr)
+    {
+        uNewErr |= X86_TRAP_PF_RSVD | X86_TRAP_PF_P;
+        Assert(!pGstWalk->Core.fNotPresent);
+    }
+    else if (!pGstWalk->Core.fNotPresent)
+        uNewErr |= X86_TRAP_PF_P;
+    TRPMSetErrorCode(pVCpu, uNewErr);
+
+    STAM_STATS({ pVCpu->pgm.s.CTX_SUFF(pStatTrap0eAttribution) = &pVCpu->pgm.s.StatRZTrap0eTime2GuestTrap; });
+    return VINF_EM_RAW_GUEST_TRAP;
+}
+# endif /* PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
+#endif /* PGM_WITH_GST_WALK */
+
+
 /**
  * #PF Handler for raw-mode guest execution.
@@ -89,4 +146,7 @@
 {
     PVM pVM = pVCpu->CTX_SUFF(pVM);
+#ifdef PGM_WITH_GST_WALK
+    int rc;
+#endif
 
     *pfLockTaken = false;
@@ -100,4 +160,89 @@
     && PGM_SHW_TYPE != PGM_TYPE_NESTED    \
     && (PGM_SHW_TYPE != PGM_TYPE_EPT || PGM_GST_TYPE == PGM_TYPE_PROT)
+
+#ifdef PGM_WITH_GST_WALK
+
+#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+    /*
+     * Walk the guest page translation tables and check if it's a guest fault.
+     */
+    GSTPTWALK GstWalk;
+    rc = PGM_GST_NAME(Walk)(pVCpu, pvFault, &GstWalk);
+    if (RT_FAILURE_NP(rc))
+        return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &GstWalk, uErr));
+#   if PGM_GST_TYPE == PGM_TYPE_AMD64
+    AssertMsg(GstWalk.Pml4e.u == GstWalk.pPml4e->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pml4e.u, (uint64_t)GstWalk.pPml4e->u));
+#   endif
+#   if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
+    AssertMsg(GstWalk.Pdpe.u == GstWalk.pPdpe->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pdpe.u, (uint64_t)GstWalk.pPdpe->u));
+#   endif
+    AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u));
+    AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u));
+
+    if (uErr & (X86_TRAP_PF_RW | X86_TRAP_PF_US | X86_TRAP_PF_ID))
+    {
+        if (    (   (uErr & X86_TRAP_PF_RW)
+                 && !GstWalk.Core.fEffectiveRW
+                 && (   (uErr & X86_TRAP_PF_US)
+                     || CPUMIsGuestR0WriteProtEnabled(pVCpu)) )
+            ||  ((uErr & X86_TRAP_PF_US) && !GstWalk.Core.fEffectiveUS)
+            ||  ((uErr & X86_TRAP_PF_ID) && GstWalk.Core.fEffectiveNX)
+           )
+            return VBOXSTRICTRC_TODO(PGM_BTH_NAME(Trap0eHandlerGuestFault)(pVCpu, &GstWalk, uErr));
+    }
+
+    /*
+     * Set the accessed and dirty flags.
+     */
+#   if PGM_GST_TYPE == PGM_TYPE_AMD64
+    GstWalk.Pml4e.u     |= X86_PML4E_A;
+    GstWalk.pPml4e->u   |= X86_PML4E_A;
+    GstWalk.Pdpe.u      |= X86_PDPE_A;
+    GstWalk.pPdpe->u    |= X86_PDPE_A;
+#   endif
+    if (GstWalk.Core.fBigPage)
+    {
+        Assert(GstWalk.Pde.b.u1Size);
+        if (uErr & X86_TRAP_PF_RW)
+        {
+            GstWalk.Pde.u   |= X86_PDE4M_A | X86_PDE4M_D;
+            GstWalk.pPde->u |= X86_PDE4M_A | X86_PDE4M_D;
+        }
+        else
+        {
+            GstWalk.Pde.u   |= X86_PDE4M_A;
+            GstWalk.pPde->u |= X86_PDE4M_A;
+        }
+    }
+    else
+    {
+        Assert(!GstWalk.Pde.b.u1Size);
+        GstWalk.Pde.u   |= X86_PDE_A;
+        GstWalk.pPde->u |= X86_PDE_A;
+        if (uErr & X86_TRAP_PF_RW)
+        {
+#   ifdef VBOX_WITH_STATISTICS
+            if (!GstWalk.Pte.n.u1Dirty)
+                STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_MID_Z(Stat,DirtiedPage));
+            else
+                STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_MID_Z(Stat,PageAlreadyDirty));
+#   endif
+            GstWalk.Pte.u   |= X86_PTE_A | X86_PTE_D;
+            GstWalk.pPte->u |= X86_PTE_A | X86_PTE_D;
+        }
+        else
+        {
+            GstWalk.Pte.u   |= X86_PTE_A;
+            GstWalk.pPte->u |= X86_PTE_A;
+        }
+        Assert(GstWalk.Pte.u == GstWalk.pPte->u);
+    }
+    AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u,
+              ("%RX64 %RX64 pPte=%p pPde=%p Pte=%RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u, GstWalk.pPte, GstWalk.pPde, (uint64_t)GstWalk.pPte->u));
+#  else  /* !PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
+    GSTPDE const PdeSrcDummy = { X86_PDE_P | X86_PDE_US | X86_PDE_RW | X86_PDE_A};
+#  endif /* !PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
+
+#else  /* !PGM_WITH_GST_WALK */
 
 #  if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE != PGM_TYPE_PAE
@@ -188,4 +333,5 @@
     }
 #  endif /* PGM_WITH_PAGING */
+#endif /* !PGM_WITH_GST_WALK */
 
     /* Take the big lock now. */
@@ -196,4 +342,5 @@
      * Fetch the guest PDE, PDPE and PML4E.
      */
+#ifndef PGM_WITH_GST_WALK
 #  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
     GSTPDE PdeSrc = pPDSrc->a[iPDSrc];
@@ -207,4 +354,5 @@
 #  endif
 
+#endif /* !PGM_WITH_GST_WALK */
 #  if PGM_SHW_TYPE == PGM_TYPE_32BIT
     const unsigned  iPDDst = pvFault >> SHW_PD_SHIFT;
@@ -215,4 +363,11 @@
 
     PX86PDPAE       pPDDst;
+#ifdef PGM_WITH_GST_WALK
+#   if PGM_GST_TYPE == PGM_TYPE_PAE
+    rc = pgmShwSyncPaePDPtr(pVCpu, pvFault, GstWalk.Pdpe.u, &pPDDst);
+#   else
+    rc = pgmShwSyncPaePDPtr(pVCpu, pvFault, X86_PDPE_P, &pPDDst);       /* RW, US and A are reserved in PAE mode. */
+#   endif
+#else
 #    if PGM_GST_TYPE != PGM_TYPE_PAE
     X86PDPE         PdpeSrc;
@@ -221,5 +376,6 @@
     PdpeSrc.u  = X86_PDPE_P;   /* rw/us are reserved for PAE pdpte's; accessed bit causes invalid VT-x guest state errors */
 #    endif
-    rc = pgmShwSyncPaePDPtr(pVCpu, pvFault, &PdpeSrc, &pPDDst);
+    rc = pgmShwSyncPaePDPtr(pVCpu, pvFault, PdpeSrc.u, &pPDDst);
+#endif
     if (rc != VINF_SUCCESS)
     {
@@ -232,4 +388,12 @@
     const unsigned  iPDDst = ((pvFault >> SHW_PD_SHIFT) & SHW_PD_MASK);
     PX86PDPAE       pPDDst;
+#ifdef PGM_WITH_GST_WALK
+#   if PGM_GST_TYPE == PGM_TYPE_PROT  /* (AMD-V nested paging) */
+    rc = pgmShwSyncLongModePDPtr(pVCpu, pvFault, X86_PML4E_P | X86_PML4E_RW | X86_PML4E_US | X86_PML4E_A,
+                                 X86_PDPE_P  | X86_PDPE_RW  | X86_PDPE_US  | X86_PDPE_A, &pPDDst);
+#   else
+    rc = pgmShwSyncLongModePDPtr(pVCpu, pvFault, GstWalk.Pml4e.u, GstWalk.Pdpe.u, &pPDDst);
+#   endif
+#else
 #   if PGM_GST_TYPE == PGM_TYPE_PROT
     /* AMD-V nested paging */
@@ -243,5 +407,6 @@
 #   endif
 
-    rc = pgmShwSyncLongModePDPtr(pVCpu, pvFault, pPml4eSrc, &PdpeSrc, &pPDDst);
+    rc = pgmShwSyncLongModePDPtr(pVCpu, pvFault, pPml4eSrc->u, PdpeSrc.u, &pPDDst);
+#endif /* !PGM_WITH_GST_WALK */
     if (rc != VINF_SUCCESS)
     {
@@ -273,5 +438,9 @@
          */
         STAM_PROFILE_START(&pVCpu->pgm.s.CTX_MID_Z(Stat,DirtyBitTracking), a);
+#ifdef PGM_WITH_GST_WALK
+        rc = PGM_BTH_NAME(CheckDirtyPageFault)(pVCpu, uErr, &pPDDst->a[iPDDst], GstWalk.pPde, pvFault);
+#else
         rc = PGM_BTH_NAME(CheckDirtyPageFault)(pVCpu, uErr, &pPDDst->a[iPDDst], &pPDSrc->a[iPDSrc], pvFault);
+#endif
         STAM_PROFILE_STOP(&pVCpu->pgm.s.CTX_MID_Z(Stat,DirtyBitTracking), a);
         if (rc == VINF_PGM_HANDLED_DIRTY_BIT_FAULT)
@@ -282,4 +451,8 @@
             return VINF_SUCCESS;
         }
+#ifdef PGM_WITH_GST_WALK
+        AssertMsg(GstWalk.Pde.u == GstWalk.pPde->u || GstWalk.pPte->u == GstWalk.pPde->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pde.u, (uint64_t)GstWalk.pPde->u));
+        AssertMsg(GstWalk.Core.fBigPage || GstWalk.Pte.u == GstWalk.pPte->u, ("%RX64 %RX64\n", (uint64_t)GstWalk.Pte.u, (uint64_t)GstWalk.pPte->u));
+#endif
     }
 
@@ -292,6 +465,7 @@
      * A common case is the not-present error caused by lazy page table syncing.
      *
-     * It is IMPORTANT that we weed out any access to non-present shadow PDEs here
-     * so we can safely assume that the shadow PT is present when calling SyncPage later.
+     * It is IMPORTANT that we weed out any access to non-present shadow PDEs
+     * here so we can safely assume that the shadow PT is present when calling
+     * SyncPage later.
      *
      * On failure, we ASSUME that SyncPT is out of memory or detected some kind
@@ -300,5 +474,11 @@
      *
      */
+#ifdef PGM_WITH_GST_WALK
+#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+    Assert(GstWalk.Pde.n.u1Present);
+#  endif
+#else
     Assert(PdeSrc.n.u1Present);
+#endif
     if (    !(uErr & X86_TRAP_PF_P) /* not set means page not present instead of page protection violation */
         &&  !pPDDst->a[iPDDst].n.u1Present
@@ -307,6 +487,16 @@
         STAM_STATS({ pVCpu->pgm.s.CTX_SUFF(pStatTrap0eAttribution) = &pVCpu->pgm.s.StatRZTrap0eTime2SyncPT; });
         STAM_PROFILE_START(&pVCpu->pgm.s.StatRZTrap0eTimeSyncPT, f);
+#ifdef PGM_WITH_GST_WALK
+#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+        LogFlow(("=>SyncPT %04x = %08RX64\n", (pvFault >> GST_PD_SHIFT) & GST_PD_MASK, (uint64_t)GstWalk.Pde.u));
+        rc = PGM_BTH_NAME(SyncPT)(pVCpu, (pvFault >> GST_PD_SHIFT) & GST_PD_MASK, GstWalk.pPd, pvFault);
+#  else
+        LogFlow(("=>SyncPT pvFault=%RGv\n", pvFault));
+        rc = PGM_BTH_NAME(SyncPT)(pVCpu, 0, NULL, pvFault);
+#  endif
+#else  /* !PGM_WITH_GST_WALK */
         LogFlow(("=>SyncPT %04x = %08x\n", iPDSrc, PdeSrc.au32[0]));
         rc = PGM_BTH_NAME(SyncPT)(pVCpu, iPDSrc, pPDSrc, pvFault);
+#endif  /* !PGM_WITH_GST_WALK */
         if (RT_SUCCESS(rc))
         {
@@ -314,5 +504,9 @@
             return rc;
         }
+#ifdef PGM_WITH_GST_WALK
+        Log(("SyncPT: %RGv failed!! rc=%Rrc\n", pvFault, rc));
+#else
         Log(("SyncPT: %d failed!! rc=%d\n", iPDSrc, rc));
+#endif
         VMCPU_FF_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3); /** @todo no need to do global sync, right? */
         STAM_PROFILE_STOP(&pVCpu->pgm.s.StatRZTrap0eTimeSyncPT, f);
@@ -345,5 +539,9 @@
                     unsigned iPT = pMapping->cb >> GST_PD_SHIFT;
                     while (iPT-- > 0)
+#ifdef PGM_WITH_GST_WALK
+                        if (GstWalk.pPde[iPT].n.u1Present)
+#else
                         if (pPDSrc->a[iPDSrc + iPT].n.u1Present)
+#endif
                         {
                             STAM_COUNTER_INC(&pVCpu->pgm.s.StatRZTrap0eConflicts);
@@ -400,6 +598,28 @@
      * in page tables which the guest believes to be present.
      */
+#ifdef PGM_WITH_GST_WALK
+#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+    Assert(GstWalk.Pde.n.u1Present);
+#  endif
+#else
     Assert(PdeSrc.n.u1Present);
-    {
+#endif
+    {
+#ifdef PGM_WITH_GST_WALK
+#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+        RTGCPHYS GCPhys = GstWalk.Core.GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+#if 1
+        RTGCPHYS GCPhys3;
+        if (    GstWalk.Pde.b.u1Size &&  GST_IS_PSE_ACTIVE(pVCpu))
+            GCPhys3 = GST_GET_PDE_BIG_PG_GCPHYS(pVM, GstWalk.Pde)
+                     | ((RTGCPHYS)pvFault & (GST_BIG_PAGE_OFFSET_MASK ^ PAGE_OFFSET_MASK));
+        else
+            GCPhys3 = GstWalk.Pte.u & GST_PTE_PG_MASK;
+        Assert(GCPhys3 == GCPhys);
+#endif
+#  else
+        RTGCPHYS GCPhys = (RTGCPHYS)pvFault & ~(RTGCPHYS)PAGE_OFFSET_MASK;
+#  endif /* PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
+#else
         RTGCPHYS    GCPhys = NIL_RTGCPHYS;
 
@@ -424,9 +644,12 @@
         GCPhys = (RTGCPHYS)(pvFault & ~PAGE_OFFSET_MASK);
 #  endif /* PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
+#endif /* !PGM_WITH_GST_WALK */
 
         /*
          * If we have a GC address we'll check if it has any flags set.
          */
+#ifndef PGM_WITH_GST_WALK
         if (GCPhys != NIL_RTGCPHYS)
+#endif
         {
             STAM_PROFILE_START(&pVCpu->pgm.s.StatRZTrap0eTimeHandlers, b);
@@ -458,5 +681,13 @@
                                 && !(uErr & X86_TRAP_PF_P))
                             {
+#ifdef PGM_WITH_GST_WALK
+#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+                                rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#   else
+                                rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrcDummy, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#   endif
+#else
                                 rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrc, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#endif
                                 if (    RT_FAILURE(rc)
                                     || !(uErr & X86_TRAP_PF_RW)
@@ -526,5 +757,9 @@
                             && !(uErr & X86_TRAP_PF_P))
                         {
+#ifdef PGM_WITH_GST_WALK
+                            rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#else
                             rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrc, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#endif
                             if (    RT_FAILURE(rc)
                                 ||  rc == VINF_PGM_SYNCPAGE_MODIFIED_PDE
@@ -623,5 +858,13 @@
                         &&  !(uErr & X86_TRAP_PF_P))
                     {
+#ifdef PGM_WITH_GST_WALK
+#  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+                        rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#  else
+                        rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrcDummy, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#  endif
+#else
                         rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrc, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#endif
                         if (    RT_FAILURE(rc)
                             ||  rc == VINF_PGM_SYNCPAGE_MODIFIED_PDE
@@ -737,6 +980,16 @@
                 uint64_t   fPageGst2;
                 PGMGstGetPage(pVCpu, pvFault, &fPageGst2, &GCPhys2);
+#ifdef PGM_WITH_GST_WALK
+#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+                Log(("Page out of sync: %RGv eip=%08x PdeSrc.US=%d fPageGst2=%08llx GCPhys2=%RGp scan=%d\n",
+                     pvFault, pRegFrame->eip, GstWalk.Pde.n.u1User, fPageGst2, GCPhys2, CSAMDoesPageNeedScanning(pVM, pRegFrame->eip)));
+#   else
+                Log(("Page out of sync: %RGv eip=%08x fPageGst2=%08llx GCPhys2=%RGp scan=%d\n",
+                     pvFault, pRegFrame->eip, fPageGst2, GCPhys2, CSAMDoesPageNeedScanning(pVM, pRegFrame->eip)));
+#   endif
+#else
                 Log(("Page out of sync: %RGv eip=%08x PdeSrc.n.u1User=%d fPageGst2=%08llx GCPhys2=%RGp scan=%d\n",
                      pvFault, pRegFrame->eip, PdeSrc.n.u1User, fPageGst2, GCPhys2, CSAMDoesPageNeedScanning(pVM, pRegFrame->eip)));
+#endif
 #   endif /* LOG_ENABLED */
 
@@ -769,5 +1022,9 @@
                                  */
                                 LogFlow(("CSAM ring 3 job\n"));
+#ifdef PGM_WITH_GST_WALK
+                                int rc2 = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, 1, uErr);
+#else
                                 int rc2 = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrc, pvFault, 1, uErr);
+#endif
                                 AssertRC(rc2);
 
@@ -818,5 +1075,13 @@
                 }
 #   endif /* PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) && !defined(IN_RING0) */
+#ifdef PGM_WITH_GST_WALK
+#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+                rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#   else
+                rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrcDummy, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#   endif
+#else
                 rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrc, pvFault, PGM_SYNC_NR_PAGES, uErr);
+#endif
                 if (RT_SUCCESS(rc))
                 {
@@ -888,5 +1153,13 @@
                      *       page is not present, which is not true in this case.
                      */
+#ifdef PGM_WITH_GST_WALK
+#   if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+                    rc = PGM_BTH_NAME(SyncPage)(pVCpu, GstWalk.Pde, pvFault, 1, uErr);
+#   else
+                    rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrcDummy, pvFault, 1, uErr);
+#   endif
+#else
                     rc = PGM_BTH_NAME(SyncPage)(pVCpu, PdeSrc, pvFault, 1, uErr);
+#endif
                     if (RT_SUCCESS(rc))
                     {
@@ -906,5 +1179,9 @@
                         {
                             rc = PGMGstGetPage(pVCpu, pvFault, &fPageGst, &GCPhys2);
-                            AssertMsg(RT_SUCCESS(rc) && (fPageGst & X86_PTE_RW), ("rc=%d fPageGst=%RX64\n"));
+#if defined(PGM_WITH_GST_WALK) && PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
+                            AssertMsg(RT_SUCCESS(rc) && (fPageGst & X86_PTE_RW), ("rc=%Rrc fPageGst=%RX64 EffRW=%d EffUS=%d uErr=%RGp cr4=%RX64 pvFault=%RGv\n", rc, fPageGst, GstWalk.Core.fEffectiveRW, GstWalk.Core.fEffectiveUS, uErr, CPUMGetGuestCR0(pVCpu), pvFault ));
+#else
+                            AssertMsg(RT_SUCCESS(rc) && (fPageGst & X86_PTE_RW), ("rc=%Rrc fPageGst=%RX64\n", rc, fPageGst));
+#endif
                             LogFlow(("Obsolete physical monitor page out of sync %RGv - phys %RGp flags=%08llx\n", pvFault, GCPhys2, (uint64_t)fPageGst));
                         }
@@ -953,4 +1230,5 @@
 #  endif /* PGM_OUT_OF_SYNC_IN_GC */
         }
+#ifndef PGM_WITH_GST_WALK
         else /* GCPhys == NIL_RTGCPHYS */
         {
@@ -970,5 +1248,7 @@
              */
         }
-    }
+#endif
+    }
+    /** @todo This point is never really reached. Clean up later!  */
 
 #  if PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE)
@@ -2437,5 +2717,5 @@
  * @param   GCPtrPage   Guest context page address.
  */
-PGM_BTH_DECL(int, CheckDirtyPageFault)(PVMCPU pVCpu, uint32_t uErr, PSHWPDE pPdeDst, PGSTPDE pPdeSrc, RTGCPTR GCPtrPage)
+PGM_BTH_DECL(int, CheckDirtyPageFault)(PVMCPU pVCpu, uint32_t uErr, PSHWPDE pPdeDst, GSTPDE const *pPdeSrc, RTGCPTR GCPtrPage)
 {
     PVM         pVM   = pVCpu->CTX_SUFF(pVM);
@@ -2506,6 +2786,6 @@
     if (pPdeDst->n.u1Present)
     {
-        PGSTPTE        pPteSrc = &pPTSrc->a[(GCPtrPage >> GST_PT_SHIFT) & GST_PT_MASK];
-        const GSTPTE   PteSrc = *pPteSrc;
+        GSTPTE const  *pPteSrc = &pPTSrc->a[(GCPtrPage >> GST_PT_SHIFT) & GST_PT_MASK];
+        const GSTPTE   PteSrc  = *pPteSrc;
 
 #ifndef IN_RING0
@@ -3348,5 +3628,5 @@
         PdpeSrc.u  = X86_PDPE_P;   /* rw/us are reserved for PAE pdpte's; accessed bit causes invalid VT-x guest state errors */
 #   endif
-        rc = pgmShwSyncPaePDPtr(pVCpu, GCPtrPage, &PdpeSrc, &pPDDst);
+        rc = pgmShwSyncPaePDPtr(pVCpu, GCPtrPage, PdpeSrc.u, &pPDDst);
         if (rc != VINF_SUCCESS)
         {
@@ -3374,5 +3654,5 @@
 #  endif
 
-        rc = pgmShwSyncLongModePDPtr(pVCpu, GCPtrPage, pPml4eSrc, &PdpeSrc, &pPDDst);
+        rc = pgmShwSyncLongModePDPtr(pVCpu, GCPtrPage, pPml4eSrc->u, PdpeSrc.u, &pPDDst);
         if (rc != VINF_SUCCESS)
         {
@@ -3510,5 +3790,5 @@
     PdpeSrc.u  = X86_PDPE_P;   /* rw/us are reserved for PAE pdpte's; accessed bit causes invalid VT-x guest state errors */
 #   endif
-    rc = pgmShwSyncPaePDPtr(pVCpu, GCPtrPage, &PdpeSrc, &pPDDst);
+    rc = pgmShwSyncPaePDPtr(pVCpu, GCPtrPage, PdpeSrc.u, &pPDDst);
     if (rc != VINF_SUCCESS)
     {
@@ -3534,5 +3814,5 @@
 #  endif
 
-    rc = pgmShwSyncLongModePDPtr(pVCpu, GCPtrPage, pPml4eSrc, &PdpeSrc, &pPDDst);
+    rc = pgmShwSyncLongModePDPtr(pVCpu, GCPtrPage, pPml4eSrc->u, PdpeSrc.u, &pPDDst);
     if (rc != VINF_SUCCESS)
     {
Index: trunk/src/VBox/VMM/VMMAll/PGMAllGst.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllGst.h	(revision 31080)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllGst.h	(revision 31081)
@@ -164,8 +164,26 @@
                 return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 2);
 
-            pWalk->Core.GCPhys     = GST_GET_PDE_BIG_PG_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
-                                   | (GCPtr & GST_BIG_PAGE_OFFSET_MASK);
-            pWalk->Core.fBigPage   = true;
-            pWalk->Core.fSucceeded = true;
+            pWalk->Core.GCPhys       = GST_GET_PDE_BIG_PG_GCPHYS(pVCpu->CTX_SUFF(pVM), Pde)
+                                     | (GCPtr & GST_BIG_PAGE_OFFSET_MASK);
+            uint8_t fEffectiveXX     = (uint8_t)pWalk->Pde.u
+#  if PGM_GST_TYPE == PGM_TYPE_AMD64
+                                     & (uint8_t)pWalk->Pde.u
+                                     & (uint8_t)pWalk->Pml4e.u
+#  endif
+                                     ;
+            pWalk->Core.fEffectiveRW = !!(fEffectiveXX & X86_PTE_RW);
+            pWalk->Core.fEffectiveUS = !!(fEffectiveXX & X86_PTE_US);
+# if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
+            pWalk->Core.fEffectiveNX = (   pWalk->Pde.n.u1NoExecute
+#  if PGM_GST_TYPE == PGM_TYPE_AMD64
+                                        || pWalk->Pde.n.u1NoExecute
+                                        || pWalk->Pml4e.n.u1NoExecute
+#  endif
+                                       ) && GST_IS_NX_ACTIVE(pVCpu);
+# else
+            pWalk->Core.fEffectiveNX = false;
+# endif
+            pWalk->Core.fBigPage     = true;
+            pWalk->Core.fSucceeded   = true;
             return VINF_SUCCESS;
         }
@@ -196,7 +214,27 @@
          * We're done.
          */
-        pWalk->Core.GCPhys     = (Pte.u & GST_PDE_PG_MASK)
-                               | (GCPtr & PAGE_OFFSET_MASK);
-        pWalk->Core.fSucceeded = true;
+        pWalk->Core.GCPhys       = (Pte.u & GST_PDE_PG_MASK)
+                                 | (GCPtr & PAGE_OFFSET_MASK);
+        uint8_t fEffectiveXX     = (uint8_t)pWalk->Pte.u
+                                 & (uint8_t)pWalk->Pde.u
+#  if PGM_GST_TYPE == PGM_TYPE_AMD64
+                                 & (uint8_t)pWalk->Pde.u
+                                 & (uint8_t)pWalk->Pml4e.u
+#  endif
+                                 ;
+        pWalk->Core.fEffectiveRW = !!(fEffectiveXX & X86_PTE_RW);
+        pWalk->Core.fEffectiveUS = !!(fEffectiveXX & X86_PTE_US);
+# if PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_GST_TYPE == PGM_TYPE_PAE
+        pWalk->Core.fEffectiveNX = (   pWalk->Pte.n.u1NoExecute
+                                    || pWalk->Pde.n.u1NoExecute
+#  if PGM_GST_TYPE == PGM_TYPE_AMD64
+                                    || pWalk->Pde.n.u1NoExecute
+                                    || pWalk->Pml4e.n.u1NoExecute
+#  endif
+                                   ) && GST_IS_NX_ACTIVE(pVCpu);
+# else
+        pWalk->Core.fEffectiveNX = false;
+# endif
+        pWalk->Core.fSucceeded   = true;
         return VINF_SUCCESS;
     }
Index: trunk/src/VBox/VMM/VMMAll/PGMAllMap.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllMap.cpp	(revision 31080)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllMap.cpp	(revision 31081)
@@ -298,5 +298,5 @@
                             GstPdpe.u = X86_PDPE_P;
                     }
-                    int rc = pgmShwSyncPaePDPtr(pVCpu, iPdPt << X86_PDPT_SHIFT, &GstPdpe, &pShwPaePd);
+                    int rc = pgmShwSyncPaePDPtr(pVCpu, iPdPt << X86_PDPT_SHIFT, GstPdpe.u, &pShwPaePd);
                     AssertFatalRC(rc);
                 }
