Index: /trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h	(revision 92332)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllGstSlatEpt.cpp.h	(revision 92333)
@@ -99,7 +99,11 @@
         Assert(!pVCpu->CTX_SUFF(pVM)->cpum.ro.GuestFeatures.fVmxModeBasedExecuteEpt);
         uint64_t const fEptAttrs     = Pml4e.u & EPT_PML4E_ATTR_MASK;
+        uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
+        uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
         uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
         uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
-        fEffective = RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
+        fEffective = RT_BF_MAKE(PGM_PTATTRS_R, fRead)
+                   | RT_BF_MAKE(PGM_PTATTRS_W, fWrite)
+                   | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
                    | fEffectiveEpt;
         pWalk->Core.fEffective = fEffective;
@@ -122,8 +126,12 @@
         {
             uint64_t const fEptAttrs     = Pdpte.u & EPT_PDPTE_ATTR_MASK;
-            uint8_t const  fAccessed     = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
+            uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
+            uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
+            uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
             uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
-            fEffective &= RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
-                       |  (fEffectiveEpt & fCumulativeEpt);
+            fEffective &= RT_BF_MAKE(PGM_PTATTRS_R, fRead)
+                        | RT_BF_MAKE(PGM_PTATTRS_W, fWrite)
+                        | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
+                        | (fEffectiveEpt & fCumulativeEpt);
             pWalk->Core.fEffective = fEffective;
         }
@@ -131,15 +139,19 @@
         {
             uint64_t const fEptAttrs     = Pdpte.u & EPT_PDPTE1G_ATTR_MASK;
+            uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
+            uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
             uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
             uint8_t const fDirty         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
             uint8_t const fMemType       = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_MEMTYPE);
             uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
-            fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
-                       |  (fEffectiveEpt & fCumulativeEpt);
+            fEffective &= RT_BF_MAKE(PGM_PTATTRS_R,           fRead)
+                        | RT_BF_MAKE(PGM_PTATTRS_W,           fWrite)
+                        | RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
+                        | (fEffectiveEpt & fCumulativeEpt);
             fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
-                       |  RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
+                        | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
             pWalk->Core.fEffective = fEffective;
 
-            pWalk->Core.fEffectiveRW = !!(fEffective & PGM_PTATTRS_RW_MASK);    /** @todo RW isn't copied from EPT R, W. This will break callers who use RW for EPT attributes. */
+            pWalk->Core.fEffectiveRW = !!fWrite;
             pWalk->Core.fEffectiveUS = true;
             pWalk->Core.fGigantPage  = true;
@@ -165,15 +177,19 @@
 
             uint64_t const fEptAttrs     = Pde.u & EPT_PDE2M_ATTR_MASK;
+            uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
+            uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
             uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
             uint8_t const fDirty         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
             uint8_t const fMemType       = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_MEMTYPE);
             uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
-
-            fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
-                       |  (fEffectiveEpt & fCumulativeEpt);
+            fEffective &= RT_BF_MAKE(PGM_PTATTRS_R,           fRead)
+                        | RT_BF_MAKE(PGM_PTATTRS_W,           fWrite)
+                        | RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
+                        | (fEffectiveEpt & fCumulativeEpt);
             fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
-                       |  RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
+                        | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
             pWalk->Core.fEffective = fEffective;
-            pWalk->Core.fEffectiveRW = !!(fEffective & PGM_PTATTRS_RW_MASK); /** @todo RW isn't copied from EPT R, W. This will break callers who use RW for EPT attributes. */
+
+            pWalk->Core.fEffectiveRW = !!fWrite;
             pWalk->Core.fEffectiveUS = true;
             pWalk->Core.fBigPage     = true;
@@ -189,9 +205,12 @@
 
         uint64_t const fEptAttrs     = Pde.u & EPT_PDE_ATTR_MASK;
+        uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
+        uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
         uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
         uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
-
-        fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,  fAccessed)
-                   |  (fEffectiveEpt & fCumulativeEpt);
+        fEffective &= RT_BF_MAKE(PGM_PTATTRS_R, fRead)
+                    | RT_BF_MAKE(PGM_PTATTRS_W, fWrite)
+                    | RT_BF_MAKE(PGM_PTATTRS_A, fAccessed)
+                    | (fEffectiveEpt & fCumulativeEpt);
         pWalk->Core.fEffective = fEffective;
 
@@ -213,15 +232,19 @@
 
         uint64_t const fEptAttrs     = Pte.u & EPT_PTE_ATTR_MASK;
+        uint8_t const fRead          = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_READ);
+        uint8_t const fWrite         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_WRITE);
         uint8_t const fAccessed      = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_ACCESSED);
         uint8_t const fDirty         = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_DIRTY);
         uint8_t const fMemType       = RT_BF_GET(fEptAttrs, VMX_BF_EPT_PT_MEMTYPE);
         uint64_t const fEffectiveEpt = (fEptAttrs << PGM_PTATTRS_EPT_SHIFT) & PGM_PTATTRS_EPT_MASK;
-        fEffective &= RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
-                   |  (fEffectiveEpt & fCumulativeEpt);
+        fEffective &= RT_BF_MAKE(PGM_PTATTRS_R,           fRead)
+                    | RT_BF_MAKE(PGM_PTATTRS_W,           fWrite)
+                    | RT_BF_MAKE(PGM_PTATTRS_A,           fAccessed)
+                    | (fEffectiveEpt & fCumulativeEpt);
         fEffective |= RT_BF_MAKE(PGM_PTATTRS_D,           fDirty)
-                   |  RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
+                    | RT_BF_MAKE(PGM_PTATTRS_EPT_MEMTYPE, fMemType);
         pWalk->Core.fEffective = fEffective;
 
-        pWalk->Core.fEffectiveRW = !!(fEffective & PGM_PTATTRS_RW_MASK); /** @todo RW isn't copied from EPT R, W. This will break callers who use RW for EPT attributes. */
+        pWalk->Core.fEffectiveRW = !!fWrite;
         pWalk->Core.fEffectiveUS = true;
         pWalk->Core.fSucceeded   = true;
