00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 setdirty.c 00008 00009 Abstract: 00010 00011 This module contains the setting dirty bit routine for memory management. 00012 00013 IA64 specific. 00014 00015 Author: 00016 00017 Lou Perazzoli (loup) 10-Apr-1990. 00018 00019 Revision History: 00020 00021 Koichi Yamada (kyamada) 9-Jan-1996 : IA64 version based on Mips 4000 version 00022 00023 --*/ 00024 00025 #include "mi.h" 00026 00027 VOID 00028 MiSetDirtyBit ( 00029 IN PVOID FaultingAddress, 00030 IN PMMPTE PointerPte, 00031 IN ULONG PfnHeld 00032 ) 00033 00034 /*++ 00035 00036 Routine Description: 00037 00038 This routine sets dirty in the specified PTE and the modify bit in the 00039 correpsonding PFN element. If any page file space is allocated, it 00040 is deallocated. 00041 00042 Arguments: 00043 00044 FaultingAddress - Supplies the faulting address. 00045 00046 PointerPte - Supplies a pointer to the corresponding valid PTE. 00047 00048 PfnHeld - Supplies TRUE if the PFN mutex is already held. 00049 00050 Return Value: 00051 00052 None. 00053 00054 Environment: 00055 00056 Kernel mode, APC's disabled, Working set mutex held. 00057 00058 --*/ 00059 00060 { 00061 MMPTE TempPte; 00062 PFN_NUMBER PageFrameIndex; 00063 PMMPFN Pfn1; 00064 KIRQL OldIrql; 00065 00066 // 00067 // The page is NOT copy on write, update the PTE setting both the 00068 // dirty bit and the accessed bit. Note, that as this PTE is in 00069 // the TB, the TB must be flushed. 00070 // 00071 00072 PageFrameIndex = MI_GET_PAGE_FRAME_FROM_PTE(PointerPte); 00073 Pfn1 = MI_PFN_ELEMENT (PageFrameIndex); 00074 00075 TempPte = *PointerPte; 00076 TempPte.u.Hard.Dirty = 1; 00077 MI_SET_ACCESSED_IN_PTE (&TempPte, 1); 00078 *PointerPte = TempPte; 00079 00080 // 00081 // Check state of PFN mutex and if not held, don't update PFN database. 00082 // 00083 00084 00085 if (PfnHeld) { 00086 00087 // 00088 // Set the modified field in the PFN database, also, if the physical 00089 // page is currently in a paging file, free up the page file space 00090 // as the contents are now worthless. 00091 // 00092 00093 if ((Pfn1->OriginalPte.u.Soft.Prototype == 0) && 00094 (Pfn1->u3.e1.WriteInProgress == 0)) { 00095 00096 // 00097 // This page is in page file format, deallocate the page file space. 00098 // 00099 00100 MiReleasePageFileSpace (Pfn1->OriginalPte); 00101 00102 // 00103 // Change original PTE to indicate no page file space is reserved, 00104 // otherwise the space will be deallocated when the PTE is 00105 // deleted. 00106 // 00107 00108 Pfn1->OriginalPte.u.Soft.PageFileHigh = 0; 00109 } 00110 00111 Pfn1->u3.e1.Modified = 1; 00112 } 00113 00114 // 00115 // The TB entry must be flushed as the valid PTE with the dirty bit clear 00116 // has been fetched into the TB. If it isn't flushed, another fault 00117 // is generated as the dirty bit is not set in the cached TB entry. 00118 // 00119 00120 KeFillEntryTb ((PHARDWARE_PTE)PointerPte, FaultingAddress, TRUE); 00121 00122 return; 00123 }