Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

211 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. checkpte.c
  5. Abstract:
  6. This module contains routines for sanity checking the page directory.
  7. Author:
  8. Lou Perazzoli (loup) 25-Apr-1989
  9. Landy Wang (landyw) 02-June-1997
  10. Revision History:
  11. --*/
  12. #include "mi.h"
  13. #if DBG
  14. VOID
  15. CheckValidPte (
  16. IN PMMPTE PointerPte
  17. );
  18. VOID
  19. MiCheckPte (
  20. VOID
  21. )
  22. /*++
  23. Routine Description:
  24. This routine checks each page table page in an address space to
  25. ensure it is in the proper state.
  26. Arguments:
  27. None.
  28. Return Value:
  29. None.
  30. Environment:
  31. Kernel mode, APCs disabled.
  32. --*/
  33. {
  34. ULONG i;
  35. ULONG j;
  36. PMMPTE PointerPte;
  37. PMMPTE PointerPde;
  38. PMMPFN Pfn1;
  39. ULONG ValidCount;
  40. ULONG TransitionCount;
  41. KIRQL OldIrql;
  42. PEPROCESS TargetProcess;
  43. USHORT UsedPages;
  44. TargetProcess = PsGetCurrentProcess ();
  45. PointerPde = MiGetPdeAddress (NULL);
  46. UsedPages = 0;
  47. LOCK_WS (TargetProcess);
  48. LOCK_PFN (OldIrql);
  49. for (i = 0; i < PDE_PER_PAGE; i += 1) {
  50. if (PointerPde->u.Hard.Valid) {
  51. ValidCount = 0;
  52. TransitionCount = 0;
  53. CheckValidPte (PointerPde);
  54. PointerPte = MiGetVirtualAddressMappedByPte (PointerPde);
  55. for (j = 0; j < PTE_PER_PAGE; j += 1) {
  56. if ((PointerPte >= MiGetPteAddress(HYPER_SPACE)) &&
  57. (PointerPte < MiGetPteAddress(WORKING_SET_LIST))) {
  58. goto endloop;
  59. }
  60. if (PointerPte->u.Hard.Valid) {
  61. ValidCount += 1;
  62. CheckValidPte (PointerPte);
  63. }
  64. else {
  65. if ((PointerPte->u.Soft.Transition == 1) &&
  66. (PointerPte->u.Soft.Prototype == 0)) {
  67. //
  68. // Transition PTE, up the transition count.
  69. //
  70. TransitionCount += 1;
  71. }
  72. }
  73. if (PointerPte->u.Long != 0) {
  74. UsedPages += 1;
  75. }
  76. endloop:
  77. PointerPte += 1;
  78. }
  79. if ((i < 512) || (i == 896)) {
  80. #if !defined (_WIN64)
  81. if (MmWorkingSetList->UsedPageTableEntries[i] != UsedPages) {
  82. DbgPrint("used pages and page table used not equal %lx %lx %lx\n",
  83. i,MmWorkingSetList->UsedPageTableEntries[i], UsedPages);
  84. }
  85. #endif
  86. }
  87. //
  88. // Check the share count for the page table page.
  89. //
  90. if ((i < 511) || (i == 896)) {
  91. Pfn1 = MI_PFN_ELEMENT (PointerPde->u.Hard.PageFrameNumber);
  92. if (Pfn1->u2.ShareCount != ((ULONG)1+ValidCount+TransitionCount)) {
  93. DbgPrint("share count for page table page bad - %lx %lx %lx\n",
  94. i,ValidCount, TransitionCount);
  95. MiFormatPfn(Pfn1);
  96. }
  97. }
  98. }
  99. PointerPde += 1;
  100. UsedPages = 0;
  101. }
  102. UNLOCK_PFN (OldIrql);
  103. UNLOCK_WS (TargetProcess);
  104. return;
  105. }
  106. VOID
  107. CheckValidPte (
  108. IN PMMPTE PointerPte
  109. )
  110. {
  111. PMMPFN Pfn1;
  112. PMMPTE PointerPde;
  113. if (MI_GET_PAGE_FRAME_FROM_PTE (PointerPte) > MmNumberOfPhysicalPages) {
  114. return;
  115. }
  116. Pfn1 = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
  117. #if 0
  118. if (PointerPte->u.Hard.PageFrameNumber == 0) {
  119. DbgPrint("physical page zero mapped\n");
  120. MiFormatPte(PointerPte);
  121. MiFormatPfn(Pfn1);
  122. }
  123. #endif
  124. if (Pfn1->u3.e1.PageLocation != ActiveAndValid) {
  125. DbgPrint("valid PTE with page frame not active and valid\n");
  126. MiFormatPfn(Pfn1);
  127. MiFormatPte(PointerPte);
  128. }
  129. if (Pfn1->u3.e1.PrototypePte == 0) {
  130. //
  131. // This is not a prototype PTE.
  132. //
  133. if (Pfn1->PteAddress != PointerPte) {
  134. DbgPrint("checkpte - Pfn PTE address and PTE address not equal\n");
  135. MiFormatPte(PointerPte);
  136. MiFormatPfn(Pfn1);
  137. return;
  138. }
  139. }
  140. if (!MmIsAddressValid(Pfn1->PteAddress)) {
  141. return;
  142. }
  143. PointerPde = MiGetPteAddress (Pfn1->PteAddress);
  144. if (PointerPde->u.Hard.Valid == 1) {
  145. if (MI_GET_PAGE_FRAME_FROM_PTE (PointerPde) != Pfn1->u4.PteFrame) {
  146. DbgPrint("checkpte - pteframe not right\n");
  147. MiFormatPfn(Pfn1);
  148. MiFormatPte(PointerPte);
  149. MiFormatPte(PointerPde);
  150. }
  151. }
  152. return;
  153. }
  154. #endif