Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

checkpfn.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 checkpfn.c 00008 00009 Abstract: 00010 00011 This module contains routines for sanity checking the PFN database. 00012 00013 Author: 00014 00015 Lou Perazzoli (loup) 25-Apr-1989 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "mi.h" 00022 00023 #if DBG 00024 00025 PRTL_BITMAP CheckPfnBitMap; 00026 00027 00028 VOID 00029 MiCheckPfn ( 00030 ) 00031 00032 /*++ 00033 00034 Routine Description: 00035 00036 This routine checks each physical page in the PFN database to ensure 00037 it is in the proper state. 00038 00039 Arguments: 00040 00041 None. 00042 00043 Return Value: 00044 00045 None. 00046 00047 Environment: 00048 00049 Kernel mode, APCs disabled. 00050 00051 --*/ 00052 00053 { 00054 PMMPFN Pfn1; 00055 PFN_NUMBER Link, Previous; 00056 ULONG i; 00057 PMMPTE PointerPte; 00058 KIRQL PreviousIrql; 00059 KIRQL OldIrql; 00060 USHORT ValidCheck[4]; 00061 USHORT ValidPage[4]; 00062 PMMPFN PfnX; 00063 00064 ValidCheck[0] = ValidCheck[1] = ValidCheck[2] = ValidCheck[3] = 0; 00065 ValidPage[0] = ValidPage[1] = ValidPage[2] = ValidPage[3] = 0; 00066 00067 if (CheckPfnBitMap == NULL) { 00068 MiCreateBitMap ( &CheckPfnBitMap, MmNumberOfPhysicalPages, NonPagedPool); 00069 } 00070 RtlClearAllBits (CheckPfnBitMap); 00071 00072 // 00073 // Walk free list. 00074 // 00075 00076 KeRaiseIrql (APC_LEVEL, &PreviousIrql); 00077 LOCK_PFN (OldIrql); 00078 00079 Previous = MM_EMPTY_LIST; 00080 Link = MmFreePageListHead.Flink; 00081 for (i=0; i < MmFreePageListHead.Total; i++) { 00082 if (Link == MM_EMPTY_LIST) { 00083 DbgPrint("free list total count wrong\n"); 00084 UNLOCK_PFN (OldIrql); 00085 KeLowerIrql (PreviousIrql); 00086 return; 00087 } 00088 RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L); 00089 Pfn1 = MI_PFN_ELEMENT(Link); 00090 if (Pfn1->u3.e2.ReferenceCount != 0) { 00091 DbgPrint("non zero reference count on free list\n"); 00092 MiFormatPfn(Pfn1); 00093 00094 } 00095 if (Pfn1->u3.e1.PageLocation != FreePageList) { 00096 DbgPrint("page location not freelist\n"); 00097 MiFormatPfn(Pfn1); 00098 } 00099 if (Pfn1->u2.Blink != Previous) { 00100 DbgPrint("bad blink on free list\n"); 00101 MiFormatPfn(Pfn1); 00102 } 00103 Previous = Link; 00104 Link = Pfn1->u1.Flink; 00105 00106 } 00107 if (Link != MM_EMPTY_LIST) { 00108 DbgPrint("free list total count wrong\n"); 00109 Pfn1 = MI_PFN_ELEMENT(Link); 00110 MiFormatPfn(Pfn1); 00111 } 00112 00113 // 00114 // Walk zeroed list. 00115 // 00116 00117 Previous = MM_EMPTY_LIST; 00118 Link = MmZeroedPageListHead.Flink; 00119 for (i=0; i < MmZeroedPageListHead.Total; i++) { 00120 if (Link == MM_EMPTY_LIST) { 00121 DbgPrint("zero list total count wrong\n"); 00122 UNLOCK_PFN (OldIrql); 00123 KeLowerIrql (PreviousIrql); 00124 return; 00125 } 00126 RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L); 00127 Pfn1 = MI_PFN_ELEMENT(Link); 00128 if (Pfn1->u3.e2.ReferenceCount != 0) { 00129 DbgPrint("non zero reference count on zero list\n"); 00130 MiFormatPfn(Pfn1); 00131 00132 } 00133 if (Pfn1->u3.e1.PageLocation != ZeroedPageList) { 00134 DbgPrint("page location not zerolist\n"); 00135 MiFormatPfn(Pfn1); 00136 } 00137 if (Pfn1->u2.Blink != Previous) { 00138 DbgPrint("bad blink on zero list\n"); 00139 MiFormatPfn(Pfn1); 00140 } 00141 Previous = Link; 00142 Link = Pfn1->u1.Flink; 00143 00144 } 00145 if (Link != MM_EMPTY_LIST) { 00146 DbgPrint("zero list total count wrong\n"); 00147 Pfn1 = MI_PFN_ELEMENT(Link); 00148 MiFormatPfn(Pfn1); 00149 } 00150 00151 // 00152 // Walk Bad list. 00153 // 00154 Previous = MM_EMPTY_LIST; 00155 Link = MmBadPageListHead.Flink; 00156 for (i=0; i < MmBadPageListHead.Total; i++) { 00157 if (Link == MM_EMPTY_LIST) { 00158 DbgPrint("Bad list total count wrong\n"); 00159 UNLOCK_PFN (OldIrql); 00160 KeLowerIrql (PreviousIrql); 00161 return; 00162 } 00163 RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L); 00164 Pfn1 = MI_PFN_ELEMENT(Link); 00165 if (Pfn1->u3.e2.ReferenceCount != 0) { 00166 DbgPrint("non zero reference count on Bad list\n"); 00167 MiFormatPfn(Pfn1); 00168 00169 } 00170 if (Pfn1->u3.e1.PageLocation != BadPageList) { 00171 DbgPrint("page location not Badlist\n"); 00172 MiFormatPfn(Pfn1); 00173 } 00174 if (Pfn1->u2.Blink != Previous) { 00175 DbgPrint("bad blink on Bad list\n"); 00176 MiFormatPfn(Pfn1); 00177 } 00178 Previous = Link; 00179 Link = Pfn1->u1.Flink; 00180 00181 } 00182 if (Link != MM_EMPTY_LIST) { 00183 DbgPrint("Bad list total count wrong\n"); 00184 Pfn1 = MI_PFN_ELEMENT(Link); 00185 MiFormatPfn(Pfn1); 00186 } 00187 00188 // 00189 // Walk Standby list. 00190 // 00191 00192 Previous = MM_EMPTY_LIST; 00193 Link = MmStandbyPageListHead.Flink; 00194 for (i=0; i < MmStandbyPageListHead.Total; i++) { 00195 if (Link == MM_EMPTY_LIST) { 00196 DbgPrint("Standby list total count wrong\n"); 00197 UNLOCK_PFN (OldIrql); 00198 KeLowerIrql (PreviousIrql); 00199 return; 00200 } 00201 RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L); 00202 Pfn1 = MI_PFN_ELEMENT(Link); 00203 if (Pfn1->u3.e2.ReferenceCount != 0) { 00204 DbgPrint("non zero reference count on Standby list\n"); 00205 MiFormatPfn(Pfn1); 00206 00207 } 00208 if (Pfn1->u3.e1.PageLocation != StandbyPageList) { 00209 DbgPrint("page location not Standbylist\n"); 00210 MiFormatPfn(Pfn1); 00211 } 00212 if (Pfn1->u2.Blink != Previous) { 00213 DbgPrint("bad blink on Standby list\n"); 00214 MiFormatPfn(Pfn1); 00215 } 00216 00217 // 00218 // Check to see if referenced PTE is okay. 00219 // 00220 if (MI_IS_PFN_DELETED (Pfn1)) { 00221 DbgPrint("Invalid pteaddress in standby list\n"); 00222 MiFormatPfn(Pfn1); 00223 00224 } else { 00225 00226 OldIrql = 99; 00227 if ((Pfn1->u3.e1.PrototypePte == 1) && 00228 (MmIsAddressValid (Pfn1->PteAddress))) { 00229 PointerPte = Pfn1->PteAddress; 00230 } else { 00231 PointerPte = MiMapPageInHyperSpace(Pfn1->PteFrame, 00232 &OldIrql); 00233 PointerPte = (PMMPTE)((ULONG_PTR)PointerPte + 00234 MiGetByteOffset(Pfn1->PteAddress)); 00235 } 00236 if (MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE (PointerPte) != Link) { 00237 DbgPrint("Invalid PFN - PTE address is wrong in standby list\n"); 00238 MiFormatPfn(Pfn1); 00239 MiFormatPte(PointerPte); 00240 } 00241 if (PointerPte->u.Soft.Transition == 0) { 00242 DbgPrint("Pte not in transition for page on standby list\n"); 00243 MiFormatPfn(Pfn1); 00244 MiFormatPte(PointerPte); 00245 } 00246 if (OldIrql != 99) { 00247 MiUnmapPageInHyperSpace (OldIrql); 00248 OldIrql = 99; 00249 } 00250 00251 } 00252 00253 Previous = Link; 00254 Link = Pfn1->u1.Flink; 00255 00256 } 00257 if (Link != MM_EMPTY_LIST) { 00258 DbgPrint("Standby list total count wrong\n"); 00259 Pfn1 = MI_PFN_ELEMENT(Link); 00260 MiFormatPfn(Pfn1); 00261 } 00262 00263 // 00264 // Walk Modified list. 00265 // 00266 00267 Previous = MM_EMPTY_LIST; 00268 Link = MmModifiedPageListHead.Flink; 00269 for (i=0; i < MmModifiedPageListHead.Total; i++) { 00270 if (Link == MM_EMPTY_LIST) { 00271 DbgPrint("Modified list total count wrong\n"); 00272 UNLOCK_PFN (OldIrql); 00273 KeLowerIrql (PreviousIrql); 00274 return; 00275 } 00276 RtlSetBits (CheckPfnBitMap, (ULONG)Link, 1L); 00277 Pfn1 = MI_PFN_ELEMENT(Link); 00278 if (Pfn1->u3.e2.ReferenceCount != 0) { 00279 DbgPrint("non zero reference count on Modified list\n"); 00280 MiFormatPfn(Pfn1); 00281 00282 } 00283 if (Pfn1->u3.e1.PageLocation != ModifiedPageList) { 00284 DbgPrint("page location not Modifiedlist\n"); 00285 MiFormatPfn(Pfn1); 00286 } 00287 if (Pfn1->u2.Blink != Previous) { 00288 DbgPrint("bad blink on Modified list\n"); 00289 MiFormatPfn(Pfn1); 00290 } 00291 // 00292 // Check to see if referenced PTE is okay. 00293 // 00294 if (MI_IS_PFN_DELETED (Pfn1)) { 00295 DbgPrint("Invalid pteaddress in modified list\n"); 00296 MiFormatPfn(Pfn1); 00297 00298 } else { 00299 00300 if ((Pfn1->u3.e1.PrototypePte == 1) && 00301 (MmIsAddressValid (Pfn1->PteAddress))) { 00302 PointerPte = Pfn1->PteAddress; 00303 } else { 00304 PointerPte = MiMapPageInHyperSpace(Pfn1->PteFrame, &OldIrql); 00305 PointerPte = (PMMPTE)((ULONG_PTR)PointerPte + 00306 MiGetByteOffset(Pfn1->PteAddress)); 00307 } 00308 00309 if (MI_GET_PAGE_FRAME_FROM_TRANSITION_PTE (PointerPte) != Link) { 00310 DbgPrint("Invalid PFN - PTE address is wrong in modified list\n"); 00311 MiFormatPfn(Pfn1); 00312 MiFormatPte(PointerPte); 00313 } 00314 if (PointerPte->u.Soft.Transition == 0) { 00315 DbgPrint("Pte not in transition for page on modified list\n"); 00316 MiFormatPfn(Pfn1); 00317 MiFormatPte(PointerPte); 00318 } 00319 00320 if (OldIrql != 99) { 00321 MiUnmapPageInHyperSpace (OldIrql); 00322 OldIrql = 99; 00323 } 00324 } 00325 00326 Previous = Link; 00327 Link = Pfn1->u1.Flink; 00328 00329 } 00330 if (Link != MM_EMPTY_LIST) { 00331 DbgPrint("Modified list total count wrong\n"); 00332 Pfn1 = MI_PFN_ELEMENT(Link); 00333 MiFormatPfn(Pfn1); 00334 } 00335 // 00336 // All non active pages have been scanned. Locate the 00337 // active pages and make sure they are consistent. 00338 // 00339 00340 // 00341 // set bit zero as page zero is reserved for now 00342 // 00343 00344 RtlSetBits (CheckPfnBitMap, 0L, 1L); 00345 00346 Link = RtlFindClearBitsAndSet (CheckPfnBitMap, 1L, 0); 00347 while (Link != 0xFFFFFFFF) { 00348 Pfn1 = MI_PFN_ELEMENT (Link); 00349 00350 // 00351 // Make sure the PTE address is okay 00352 // 00353 00354 if ((Pfn1->PteAddress >= (PMMPTE)HYPER_SPACE) 00355 && (Pfn1->u3.e1.PrototypePte == 0)) { 00356 DbgPrint("pfn with illegal pte address\n"); 00357 MiFormatPfn(Pfn1); 00358 break; 00359 } 00360 00361 if (Pfn1->PteAddress < (PMMPTE)PTE_BASE) { 00362 DbgPrint("pfn with illegal pte address\n"); 00363 MiFormatPfn(Pfn1); 00364 break; 00365 } 00366 00367 #if defined(_IA64_) 00368 00369 // 00370 // ignore PTEs mapped to IA64 kernel BAT. 00371 // 00372 00373 if (MI_IS_PHYSICAL_ADDRESS(MiGetVirtualAddressMappedByPte(Pfn1->PteAddress))) { 00374 00375 goto NoCheck; 00376 } 00377 #endif // _IA64_ 00378 00379 #ifdef _ALPHA_ 00380 00381 // 00382 // ignore ptes mapped to ALPHA's 32-bit superpage. 00383 // 00384 00385 if ((Pfn1->PteAddress > (PMMPTE)(ULONG_PTR)0xc0100000) && 00386 (Pfn1->PteAddress < (PMMPTE)(ULONG_PTR)0xc0180000)) { 00387 00388 goto NoCheck; 00389 } 00390 #endif //ALPHA 00391 00392 // 00393 // Check to make sure the referenced PTE is for this page. 00394 // 00395 00396 if ((Pfn1->u3.e1.PrototypePte == 1) && 00397 (MmIsAddressValid (Pfn1->PteAddress))) { 00398 PointerPte = Pfn1->PteAddress; 00399 } else { 00400 PointerPte = MiMapPageInHyperSpace(Pfn1->PteFrame, &OldIrql); 00401 PointerPte = (PMMPTE)((ULONG_PTR)PointerPte + 00402 MiGetByteOffset(Pfn1->PteAddress)); 00403 } 00404 00405 if (MI_GET_PAGE_FRAME_FROM_PTE (PointerPte) != Link) { 00406 DbgPrint("Invalid PFN - PTE address is wrong in active list\n"); 00407 MiFormatPfn(Pfn1); 00408 MiFormatPte(PointerPte); 00409 } 00410 if (PointerPte->u.Hard.Valid == 0) { 00411 // 00412 // if the page is a page table page it could be out of 00413 // the working set yet a transition page is keeping it 00414 // around in memory (ups the share count). 00415 // 00416 00417 if ((Pfn1->PteAddress < (PMMPTE)PDE_BASE) || 00418 (Pfn1->PteAddress > (PMMPTE)PDE_TOP)) { 00419 00420 DbgPrint("Pte not valid for page on active list\n"); 00421 MiFormatPfn(Pfn1); 00422 MiFormatPte(PointerPte); 00423 } 00424 } 00425 00426 if (Pfn1->u3.e2.ReferenceCount != 1) { 00427 DbgPrint("refcount not 1\n"); 00428 MiFormatPfn(Pfn1); 00429 } 00430 00431 00432 // 00433 // Check to make sure the PTE count for the frame is okay. 00434 // 00435 00436 if (Pfn1->u3.e1.PrototypePte == 1) { 00437 PfnX = MI_PFN_ELEMENT(Pfn1->PteFrame); 00438 for (i = 0; i < 4; i++) { 00439 if (ValidPage[i] == 0) { 00440 ValidPage[i] = (USHORT)Pfn1->PteFrame; 00441 } 00442 if (ValidPage[i] == (USHORT)Pfn1->PteFrame) { 00443 ValidCheck[i] += 1; 00444 break; 00445 } 00446 } 00447 } 00448 if (OldIrql != 99) { 00449 MiUnmapPageInHyperSpace (OldIrql); 00450 OldIrql = 99; 00451 } 00452 00453 #if defined(_ALPHA_) || defined(_IA64_) 00454 NoCheck: 00455 #endif 00456 Link = RtlFindClearBitsAndSet (CheckPfnBitMap, 1L, 0); 00457 00458 } 00459 00460 for (i = 0; i < 4; i++) { 00461 if (ValidPage[i] == 0) { 00462 break; 00463 } 00464 PfnX = MI_PFN_ELEMENT(ValidPage[i]); 00465 } 00466 00467 UNLOCK_PFN (OldIrql); 00468 KeLowerIrql (PreviousIrql); 00469 return; 00470 00471 } 00472 00473 VOID 00474 MiDumpPfn ( ) 00475 00476 { 00477 ULONG i; 00478 PMMPFN Pfn1; 00479 00480 Pfn1 = MI_PFN_ELEMENT (MmLowestPhysicalPage); 00481 00482 for (i=0; i < MmNumberOfPhysicalPages; i++) { 00483 MiFormatPfn (Pfn1); 00484 Pfn1++; 00485 } 00486 return; 00487 } 00488 00489 VOID 00490 MiFormatPfn ( 00491 IN PMMPFN PointerPfn 00492 ) 00493 00494 { 00495 00496 MMPFN Pfn; 00497 ULONG i; 00498 00499 Pfn = *PointerPfn; 00500 i = (ULONG)(PointerPfn - MmPfnDatabase); 00501 00502 DbgPrint("***PFN %lx flink %lx blink %lx ptecount-refcnt %lx\n", 00503 i, 00504 Pfn.u1.Flink, 00505 Pfn.u2.Blink, 00506 Pfn.u3.e2.ReferenceCount); 00507 00508 DbgPrint(" pteaddr %p originalPTE %p flags %lx \n", 00509 Pfn.PteAddress, 00510 Pfn.OriginalPte, 00511 Pfn.u3.e2.ShortFlags); 00512 00513 return; 00514 00515 } 00516 #endif //DBG

Generated on Sat May 15 19:39:23 2004 for test by doxygen 1.3.7