Index: trunk/src/VBox/VMM/VMMAll/PGMAllGst.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PGMAllGst.h	(revision 92330)
+++ trunk/src/VBox/VMM/VMMAll/PGMAllGst.h	(revision 92331)
@@ -149,5 +149,5 @@
 # endif
 
-    uint64_t fEffective = X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A | 1;  /** @todo can this default assignment be removed? */
+    uint64_t fEffective;
     {
 # if PGM_GST_TYPE == PGM_TYPE_AMD64
@@ -170,5 +170,5 @@
         else return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 4);
 
-        pWalk->Core.fEffective = fEffective = Pml4e.u & (  X86_PML4E_RW  | X86_PML4E_US | X86_PML4E_PWT
+        pWalk->Core.fEffective = fEffective = Pml4e.u & (  X86_PML4E_P   | X86_PML4E_RW | X86_PML4E_US | X86_PML4E_PWT
                                                          | X86_PML4E_PCD | X86_PML4E_A  | X86_PML4E_NX);
 
@@ -204,9 +204,10 @@
 
 # if PGM_GST_TYPE == PGM_TYPE_AMD64
-        pWalk->Core.fEffective = fEffective &= (Pdpe.u & (X86_PDPE_RW | X86_PDPE_US | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
+        pWalk->Core.fEffective = fEffective &= (Pdpe.u & (  X86_PDPE_P   | X86_PDPE_RW  | X86_PDPE_US
+                                                          | X86_PDPE_PWT | X86_PDPE_PCD | X86_PDPE_A))
                                              | (Pdpe.u & X86_PDPE_LM_NX);
 # else
         /* NX in the legacy-mode PAE PDPE is reserved. The valid check above ensures the NX bit is not set. */
-        pWalk->Core.fEffective = fEffective  = X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
+        pWalk->Core.fEffective = fEffective  = X86_PDPE_P | X86_PDPE_RW  | X86_PDPE_US | X86_PDPE_A
                                              | (Pdpe.u & (X86_PDPE_PWT | X86_PDPE_PCD));
 # endif
@@ -245,7 +246,7 @@
              */
 # if PGM_GST_TYPE == PGM_TYPE_32BIT
-            fEffective &=  Pde.u & (X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A);
+            fEffective  =  Pde.u & (X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A);
 # else
-            fEffective &= (Pde.u & (X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A))
+            fEffective &= (Pde.u & (X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PWT | X86_PDE4M_PCD | X86_PDE4M_A))
                         | (Pde.u & X86_PDE2M_PAE_NX);
 # endif
@@ -254,4 +255,5 @@
             pWalk->Core.fEffective = fEffective;
             Assert(GST_IS_NX_ACTIVE(pVCpu) || !(fEffective & PGM_PTATTRS_NX_MASK));
+            Assert(fEffective & PGM_PTATTRS_R_MASK);
 
             pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
@@ -273,7 +275,9 @@
             return PGM_GST_NAME(WalkReturnRsvdError)(pVCpu, pWalk, 2);
 # if PGM_GST_TYPE == PGM_TYPE_32BIT
-        pWalk->Core.fEffective = fEffective &= Pde.u & (X86_PDE_RW | X86_PDE_US | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
+        pWalk->Core.fEffective = fEffective  = Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
+                                                        | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A);
 # else
-        pWalk->Core.fEffective = fEffective &= (Pde.u & (X86_PDE_RW | X86_PDE_US | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
+        pWalk->Core.fEffective = fEffective &= (Pde.u & (  X86_PDE_P   | X86_PDE_RW  | X86_PDE_US
+                                                         | X86_PDE_PWT | X86_PDE_PCD | X86_PDE_A))
                                              | (Pde.u & X86_PDE_PAE_NX);
 # endif
@@ -306,7 +310,7 @@
          */
 # if PGM_GST_TYPE == PGM_TYPE_32BIT
-        fEffective &= Pte.u & (X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A);
+        fEffective &=  Pte.u & (X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A);
 # else
-        fEffective &= (Pte.u & (X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A))
+        fEffective &= (Pte.u & (X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_PWT | X86_PTE_PCD | X86_PTE_A))
                    |  (Pte.u & X86_PTE_PAE_NX);
 # endif
@@ -314,4 +318,5 @@
         pWalk->Core.fEffective = fEffective;
         Assert(GST_IS_NX_ACTIVE(pVCpu) || !(fEffective & PGM_PTATTRS_NX_MASK));
+        Assert(fEffective & PGM_PTATTRS_R_MASK);
 
         pWalk->Core.fEffectiveRW = !!(fEffective & X86_PTE_RW);
@@ -376,5 +381,5 @@
         if (!Walk.Core.fBigPage)
             *pfFlags = (Walk.Pte.u & ~(GST_PTE_PG_MASK | X86_PTE_RW | X86_PTE_US))                      /* NX not needed */
-                     | (Walk.Core.fEffective & (  PGM_PTATTRS_RW_MASK
+                     | (Walk.Core.fEffective & (  PGM_PTATTRS_W_MASK
                                                 | PGM_PTATTRS_US_MASK))
 # if PGM_WITH_NX(PGM_GST_TYPE, PGM_GST_TYPE)
@@ -385,5 +390,5 @@
         {
             *pfFlags = (Walk.Pde.u & ~(GST_PTE_PG_MASK | X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PS))   /* NX not needed */
-                     | (Walk.Core.fEffective & (  PGM_PTATTRS_RW_MASK
+                     | (Walk.Core.fEffective & (  PGM_PTATTRS_W_MASK
                                                 | PGM_PTATTRS_US_MASK
                                                 | PGM_PTATTRS_PAT_MASK))
Index: trunk/src/VBox/VMM/include/PGMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/PGMInternal.h	(revision 92330)
+++ trunk/src/VBox/VMM/include/PGMInternal.h	(revision 92331)
@@ -2341,10 +2341,13 @@
  * The following bits map 1:1 (shifted by PGM_PTATTRS_EPT_SHIFT) to the Intel EPT
  * attributes as these are unique to EPT and fit within 64-bits despite the shift:
- *   - R           (Read access).
- *   - W           (Write access).
- *   - X_SUPER     (Execute or execute access for supervisor-mode linear addresses).
+ *   - EPT_R       (Read access).
+ *   - EPT_W       (Write access).
+ *   - EPT_X_SUPER (Execute or execute access for supervisor-mode linear addresses).
  *   - EPT_MEMTYPE (EPT memory type).
  *   - IGNORE_PAT  (Ignore PAT memory type).
  *   - X_USER      (Execute access for user-mode linear addresses).
+ *
+ * For regular page tables, the R bit is always 1 (same as P bit).
+ * For Intel EPT, the EPT_R and EPT_W bits are copied to R and W bits respectively.
  *
  * The following EPT attributes are mapped to the following positions because they
@@ -2366,10 +2369,10 @@
 typedef PGMPTATTRS *PPGMPTATTRS;
 
-/** Reserved bit. */
-#define PGM_PTATTRS_RSVD_0_SHIFT                    0
-#define PGM_PTATTRS_RSVD_0_MASK                     RT_BIT_64(PGM_PTATTRS_RSVD_0_SHIFT)
-/** Read and write access bit. */
-#define PGM_PTATTRS_RW_SHIFT                        1
-#define PGM_PTATTRS_RW_MASK                         RT_BIT_64(PGM_PTATTRS_RW_SHIFT)
+/** Read bit (always 1 for regular PT, copy of EPT_R for EPT). */
+#define PGM_PTATTRS_R_SHIFT                         0
+#define PGM_PTATTRS_R_MASK                          RT_BIT_64(PGM_PTATTRS_R_SHIFT)
+/** Write access bit (aka read/write bit for regular PT). */
+#define PGM_PTATTRS_W_SHIFT                         1
+#define PGM_PTATTRS_W_MASK                          RT_BIT_64(PGM_PTATTRS_W_SHIFT)
 /** User-mode access bit. */
 #define PGM_PTATTRS_US_SHIFT                        2
@@ -2434,7 +2437,6 @@
 
 RT_BF_ASSERT_COMPILE_CHECKS(PGM_PTATTRS_, UINT64_C(0), UINT64_MAX,
-                            (RSVD_0, RW, US, PWT, PCD, A, D, PAT, G, RSVD_12_9, EPT_R, EPT_W, EPT_X_SUPER, EPT_MEMTYPE,
-                             EPT_IGNORE_PAT, RSVD_22_20, EPT_X_USER, RSVD_23, EPT_SUPER_SHW_STACK, EPT_SUPPRESS_VE_XCPT,
-                             RSVD_62_27, NX));
+                            (R, W, US, PWT, PCD, A, D, PAT, G, RSVD_12_9, EPT_R, EPT_W, EPT_X_SUPER, EPT_MEMTYPE, EPT_IGNORE_PAT,
+                             RSVD_22_20, EPT_X_USER, RSVD_23, EPT_SUPER_SHW_STACK, EPT_SUPPRESS_VE_XCPT, RSVD_62_27, NX));
 
 /** The bit position where the EPT specific attributes begin. */
@@ -2445,5 +2447,6 @@
 
 /** The mask of all PGM page attribute bits for regular page-tables. */
-#define PGM_PTATTRS_PT_VALID_MASK                   (  PGM_PTATTRS_RW_MASK \
+#define PGM_PTATTRS_PT_VALID_MASK                   (  PGM_PTATTRS_R_MASK \
+                                                     | PGM_PTATTRS_W_MASK \
                                                      | PGM_PTATTRS_US_MASK \
                                                      | PGM_PTATTRS_PWT_MASK \
@@ -2456,8 +2459,10 @@
 
 /** The mask of all PGM page attribute bits for EPT. */
-#define PGM_PTATTRS_EPT_VALID_MASK                  (  PGM_PTATTRS_A_MASK \
+#define PGM_PTATTRS_EPT_VALID_MASK                  (  PGM_PTATTRS_R_MASK \
+                                                     | PGM_PTATTRS_W_MASK \
+                                                     | PGM_PTATTRS_A_MASK \
                                                      | PGM_PTATTRS_D_MASK \
-                                                     | PGM_PTATTRS_R_MASK \
-                                                     | PGM_PTATTRS_W_MASK \
+                                                     | PGM_PTATTRS_EPT_R_MASK \
+                                                     | PGM_PTATTRS_EPT_W_MASK \
                                                      | PGM_PTATTRS_EPT_X_SUPER \
                                                      | PGM_PTATTRS_EPT_MEMTYPE \
@@ -2471,5 +2476,5 @@
 
 /* Verify bits match the regular PT bits. */
-AssertCompile(PGM_PTATTRS_RW_SHIFT  == X86_PTE_BIT_RW);
+AssertCompile(PGM_PTATTRS_W_SHIFT   == X86_PTE_BIT_RW);
 AssertCompile(PGM_PTATTRS_US_SHIFT  == X86_PTE_BIT_US);
 AssertCompile(PGM_PTATTRS_PWT_SHIFT == X86_PTE_BIT_PWT);
@@ -2479,5 +2484,5 @@
 AssertCompile(PGM_PTATTRS_PAT_SHIFT == X86_PTE_BIT_PAT);
 AssertCompile(PGM_PTATTRS_G_SHIFT   == X86_PTE_BIT_G);
-AssertCompile(PGM_PTATTRS_RW_MASK   == X86_PTE_RW);
+AssertCompile(PGM_PTATTRS_W_MASK    == X86_PTE_RW);
 AssertCompile(PGM_PTATTRS_US_MASK   == X86_PTE_US);
 AssertCompile(PGM_PTATTRS_PWT_MASK  == X86_PTE_PWT);
