[NTOS:MM] Pass page fault code to MmAccessFault
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 1 Jan 2018 14:25:45 +0000 (15:25 +0100)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 6 Jan 2018 17:20:24 +0000 (18:20 +0100)
Note: before we had a BOOLEAN parameter called StoreInstruction, but in reality it was not specifying whether the fault was from a store store instruction, but whether it was an access violation rather than a page-not-present fault. On x86 without PAE there are only 2 kinds of access violations: (1) Access of a kernel mode page from user mode, which is handled early and (2) access of a read-only (or COW) page with a writing instruction. Therefore we could get away with this, even though it relied on the wrong assumption that a fault, which was not a page-not-present-fault, was automatically a write access. This commit only changes one thing: we pass the full fault-code to MmAccessFault and handle the rest from there in exactly the same way as before. More changes are coming to make things clear.

ntoskrnl/include/internal/amd64/mm.h
ntoskrnl/include/internal/arm/mm.h
ntoskrnl/include/internal/i386/mm.h
ntoskrnl/include/internal/mm.h
ntoskrnl/ke/amd64/trap.S
ntoskrnl/ke/arm/trapc.c
ntoskrnl/ke/i386/traphdlr.c
ntoskrnl/mm/mmfault.c

index 2248ab4..0d28381 100644 (file)
 #define MI_MAKE_WRITE_PAGE(x)      ((x)->u.Hard.Writable = 1)
 #endif
 
+/* Macros to identify the page fault reason from the error code */
+#define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
+
 /* On x64, these are the same */
 #define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE
 #define ValidKernelPpe ValidKernelPde
index 71468cc..bc26ab7 100644 (file)
@@ -88,6 +88,9 @@
 #define MI_MAKE_OWNER_PAGE(x)      ((x)->u.Hard.Owner = 1)
 #define MI_MAKE_WRITE_PAGE(x)      ((x)->u.Hard.ReadOnly = 0)
 
+/* Macros to identify the page fault reason from the error code */
+#define MI_IS_NOT_PRESENT_FAULT(FaultCode) TRUE
+
 /* Convert an address to a corresponding PTE */
 #define MiAddressToPte(x) \
     ((PMMPTE)(PTE_BASE + (((ULONG)(x) >> 12) << 2)))
index 19ce1c8..d38ab01 100644 (file)
 #define MI_MAKE_WRITE_PAGE(x)      ((x)->u.Hard.Writable = 1)
 #endif
 
+
+/* Macros to identify the page fault reason from the error code */
+#define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x1)
+
 /* On x86, these two are the same */
 #define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE
 
index ec42abb..4489530 100644 (file)
@@ -744,7 +744,7 @@ MmFreeSpecialPool(
 NTSTATUS
 NTAPI
 MmAccessFault(
-    IN BOOLEAN StoreInstruction,
+    IN ULONG FaultCode,
     IN PVOID Address,
     IN KPROCESSOR_MODE Mode,
     IN PVOID TrapInformation
index 750e21c..3a017b8 100644 (file)
@@ -503,8 +503,7 @@ FUNC KiPageFault
     sti
 
     /* Call page fault handler */
-    mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction
-    and ecx, 1
+    mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // FaultCode
     // rdx == Address
     mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode
     and r8b, 1
index bf1c8ac..0f94c17 100644 (file)
@@ -529,7 +529,7 @@ KiDataAbortHandler(IN PKTRAP_FRAME TrapFrame)
     //
     if (KeArmFaultStatusRegisterGet() == 21 || KeArmFaultStatusRegisterGet() == 23)
     {
-        Status = MmAccessFault(FALSE,
+        Status = MmAccessFault(KeArmFaultStatusRegisterGet(),
                                Address,
                                KiGetPreviousMode(TrapFrame),
                                TrapFrame);
index 0a8cf6f..27ae26c 100644 (file)
@@ -1199,7 +1199,6 @@ FASTCALL
 KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
 {
     PKTHREAD Thread;
-    BOOLEAN Present;
     BOOLEAN StoreInstruction;
     ULONG_PTR Cr2;
     NTSTATUS Status;
@@ -1227,7 +1226,6 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
     _enable();
 
     /* Interpret the error code */
-    Present = (TrapFrame->ErrCode & 1) != 0;
     StoreInstruction = (TrapFrame->ErrCode & 2) != 0;
 
     /* Check if we came in with interrupts disabled */
@@ -1237,7 +1235,7 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
         KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
                          Cr2,
                          (ULONG_PTR)-1,
-                         StoreInstruction,
+                         TrapFrame->ErrCode,
                          TrapFrame->Eip,
                          TrapFrame);
     }
@@ -1339,7 +1337,7 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
 NotSListFault:
 
     /* Call the access fault handler */
-    Status = MmAccessFault(Present,
+    Status = MmAccessFault(TrapFrame->ErrCode,
                            (PVOID)Cr2,
                            KiUserTrap(TrapFrame),
                            TrapFrame);
index 8750be3..12774d6 100644 (file)
@@ -201,12 +201,13 @@ extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address);
 
 NTSTATUS
 NTAPI
-MmAccessFault(IN BOOLEAN StoreInstruction,
+MmAccessFault(IN ULONG FaultCode,
               IN PVOID Address,
               IN KPROCESSOR_MODE Mode,
               IN PVOID TrapInformation)
 {
     PMEMORY_AREA MemoryArea = NULL;
+    BOOLEAN StoreInstruction = !MI_IS_NOT_PRESENT_FAULT(FaultCode);
 
     /* Cute little hack for ROS */
     if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)