https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3021c2d571ad04c60840f2...
commit 3021c2d571ad04c60840f2dcdf46af67b13f4c4d Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Mon Jan 1 15:25:45 2018 +0100
[NTOS:MM] Pass page fault code to MmAccessFault 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 thou [...] --- ntoskrnl/include/internal/amd64/mm.h | 3 +++ ntoskrnl/include/internal/arm/mm.h | 3 +++ ntoskrnl/include/internal/i386/mm.h | 4 ++++ ntoskrnl/include/internal/mm.h | 2 +- ntoskrnl/ke/amd64/trap.S | 3 +-- ntoskrnl/ke/arm/trapc.c | 2 +- ntoskrnl/ke/i386/traphdlr.c | 6 ++---- ntoskrnl/mm/mmfault.c | 3 ++- 8 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/ntoskrnl/include/internal/amd64/mm.h b/ntoskrnl/include/internal/amd64/mm.h index 2248ab490e..0d28381422 100644 --- a/ntoskrnl/include/internal/amd64/mm.h +++ b/ntoskrnl/include/internal/amd64/mm.h @@ -106,6 +106,9 @@ #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 diff --git a/ntoskrnl/include/internal/arm/mm.h b/ntoskrnl/include/internal/arm/mm.h index 71468cce56..bc26ab72d8 100644 --- a/ntoskrnl/include/internal/arm/mm.h +++ b/ntoskrnl/include/internal/arm/mm.h @@ -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))) diff --git a/ntoskrnl/include/internal/i386/mm.h b/ntoskrnl/include/internal/i386/mm.h index 19ce1c82a6..d38ab01c31 100644 --- a/ntoskrnl/include/internal/i386/mm.h +++ b/ntoskrnl/include/internal/i386/mm.h @@ -111,6 +111,10 @@ #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
diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index ec42abbfae..4489530ee2 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -744,7 +744,7 @@ MmFreeSpecialPool( NTSTATUS NTAPI MmAccessFault( - IN BOOLEAN StoreInstruction, + IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation diff --git a/ntoskrnl/ke/amd64/trap.S b/ntoskrnl/ke/amd64/trap.S index 750e21c048..3a017b85b7 100644 --- a/ntoskrnl/ke/amd64/trap.S +++ b/ntoskrnl/ke/amd64/trap.S @@ -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 diff --git a/ntoskrnl/ke/arm/trapc.c b/ntoskrnl/ke/arm/trapc.c index bf1c8acdc8..0f94c17ea9 100644 --- a/ntoskrnl/ke/arm/trapc.c +++ b/ntoskrnl/ke/arm/trapc.c @@ -529,7 +529,7 @@ KiDataAbortHandler(IN PKTRAP_FRAME TrapFrame) // if (KeArmFaultStatusRegisterGet() == 21 || KeArmFaultStatusRegisterGet() == 23) { - Status = MmAccessFault(FALSE, + Status = MmAccessFault(KeArmFaultStatusRegisterGet(), Address, KiGetPreviousMode(TrapFrame), TrapFrame); diff --git a/ntoskrnl/ke/i386/traphdlr.c b/ntoskrnl/ke/i386/traphdlr.c index 0a8cf6ffc3..27ae26c805 100644 --- a/ntoskrnl/ke/i386/traphdlr.c +++ b/ntoskrnl/ke/i386/traphdlr.c @@ -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); diff --git a/ntoskrnl/mm/mmfault.c b/ntoskrnl/mm/mmfault.c index 8750be3fac..12774d6ebb 100644 --- a/ntoskrnl/mm/mmfault.c +++ b/ntoskrnl/mm/mmfault.c @@ -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)