summaryrefslogtreecommitdiffstats
path: root/private/ntos/mm/checkpte.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/mm/checkpte.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/mm/checkpte.c')
-rw-r--r--private/ntos/mm/checkpte.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/private/ntos/mm/checkpte.c b/private/ntos/mm/checkpte.c
new file mode 100644
index 000000000..a2133604b
--- /dev/null
+++ b/private/ntos/mm/checkpte.c
@@ -0,0 +1,235 @@
+/*++
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ checkpte.c
+
+Abstract:
+
+ This module contains routines for sanity checking the page directory.
+
+Author:
+
+ Lou Perazzoli (loup) 25-Apr-1989
+
+Revision History:
+
+--*/
+
+#include "mi.h"
+
+#if DBG
+
+VOID
+CheckValidPte (
+ IN PMMPTE PointerPte
+ );
+
+VOID
+CheckInvalidPte (
+ IN PMMPTE PointerPte
+ );
+
+
+VOID
+MiCheckPte (
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine checks each page table page in an address space to
+ ensure it is in the proper state.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+Environment:
+
+ Kernel mode, APC's disabled.
+
+--*/
+
+{
+ ULONG i,j;
+ PMMPTE PointerPte;
+ PMMPTE PointerPde;
+ PMMPFN Pfn1;
+ ULONG ValidCount;
+ ULONG TransitionCount;
+ KIRQL PreviousIrql;
+ KIRQL OldIrql;
+ PEPROCESS TargetProcess;
+ USHORT UsedPages;
+ ULONG PdeValidCount;
+
+ TargetProcess = PsGetCurrentProcess ();
+
+ KeRaiseIrql (APC_LEVEL, &PreviousIrql);
+
+ LOCK_WS (TargetProcess);
+ LOCK_PFN (OldIrql);
+
+ PointerPde = MiGetPdeAddress(0);
+
+ UsedPages = 0;
+ PdeValidCount = 1;
+
+ for (i = 0; i < PDE_PER_PAGE; i++) {
+ if (PointerPde->u.Hard.Valid) {
+
+ if ((i < 512) || (i == 769) || (i== 896) ) {
+ PdeValidCount += 1;
+ }
+
+ ValidCount = 0;
+ TransitionCount = 0;
+ CheckValidPte (PointerPde);
+
+ PointerPte = MiGetPteAddress (i<<22);
+
+ for (j=0; j < PTE_PER_PAGE; j++) {
+
+ if ((PointerPte >= MiGetPteAddress(HYPER_SPACE)) &&
+ (PointerPte < MiGetPteAddress(WORKING_SET_LIST))) {
+ goto endloop;
+ }
+
+ if (PointerPte->u.Hard.Valid) {
+ ValidCount += 1;
+ CheckValidPte (PointerPte);
+
+ } else {
+ CheckInvalidPte (PointerPte);
+
+ if ((PointerPte->u.Soft.Transition == 1) &&
+ (PointerPte->u.Soft.Prototype == 0)) {
+
+ //
+ // Transition PTE, up the transition count.
+ //
+
+ TransitionCount += 1;
+
+ }
+ }
+
+ if (PointerPte->u.Long != 0) {
+ UsedPages += 1;
+ }
+endloop:
+ PointerPte++;
+
+ }
+ if ((i < 512) || (i == 896)) {
+ if (MmWorkingSetList->UsedPageTableEntries[i] != UsedPages) {
+ DbgPrint("used pages and page table used not equal %lx %lx %lx\n",
+ i,MmWorkingSetList->UsedPageTableEntries[i], UsedPages);
+ }
+ }
+
+ //
+ // Check the share count for the page table page.
+ //
+ if ((i < 511) || (i == 896)) {
+ Pfn1 = MI_PFN_ELEMENT (PointerPde->u.Hard.PageFrameNumber);
+ if (Pfn1->u2.ShareCount != ((ULONG)1+ValidCount+TransitionCount)) {
+ DbgPrint("share count for page table page bad - %lx %lx %lx\n",
+ i,ValidCount, TransitionCount);
+ MiFormatPfn(Pfn1);
+ }
+ }
+ }
+ PointerPde++;
+ UsedPages = 0;
+ }
+
+ PointerPde = (PMMPTE)0xc0300c00;
+ Pfn1 = MI_PFN_ELEMENT(PointerPde->u.Hard.PageFrameNumber);
+ UNLOCK_PFN (OldIrql);
+ UNLOCK_WS (TargetProcess);
+ KeLowerIrql (PreviousIrql);
+ return;
+
+}
+
+VOID
+CheckValidPte (
+ IN PMMPTE PointerPte
+ )
+
+{
+ PMMPFN Pfn1;
+ PMMPTE PointerPde;
+
+ if (PointerPte->u.Hard.PageFrameNumber > MmNumberOfPhysicalPages) {
+ return;
+ }
+
+
+ Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
+
+ if (PointerPte->u.Hard.PageFrameNumber == 0) {
+ DbgPrint("physical page zero mapped\n");
+ MiFormatPte(PointerPte);
+ MiFormatPfn(Pfn1);
+ }
+
+ if (Pfn1->u3.e1.PageLocation != ActiveAndValid) {
+ DbgPrint("valid PTE with page frame not active and valid\n");
+ MiFormatPfn(Pfn1);
+ MiFormatPte(PointerPte);
+ }
+
+ if (Pfn1->u3.e1.PrototypePte == 0) {
+ //
+ // This is not a prototype PTE.
+ //
+ if (Pfn1->PteAddress != PointerPte) {
+ DbgPrint("checkpte - pfn pte address and pte address not equal\n");
+ MiFormatPte(PointerPte);
+ MiFormatPfn(Pfn1);
+ return;
+ }
+
+ }
+
+ if (!MmIsAddressValid(Pfn1->PteAddress)) {
+ return;
+ }
+
+ PointerPde = MiGetPteAddress (Pfn1->PteAddress);
+ if (PointerPde->u.Hard.Valid == 1) {
+
+ if (PointerPde->u.Hard.PageFrameNumber != Pfn1->PteFrame) {
+ DbgPrint("checkpte - pteframe not right\n");
+ MiFormatPfn(Pfn1);
+ MiFormatPte(PointerPte);
+ MiFormatPte(PointerPde);
+ }
+ }
+ return;
+
+}
+
+VOID
+CheckInvalidPte (
+ IN PMMPTE PointerPte
+ )
+
+
+{
+ PointerPte;
+ return;
+
+}
+#endif //DBG