00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 Copyright (c) 1992 Digital Equipment Corporation 00005 00006 Module Name: 00007 00008 setdirty.c 00009 00010 Abstract: 00011 00012 This module contains the setting dirty bit routine for memory management. 00013 00014 ALPHA specific. 00015 00016 Author: 00017 00018 Lou Perazzoli (loup) 10-Apr-1990. 00019 Joe Notarangelo 23-Apr-1992 ALPHA version 00020 00021 Revision History: 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 TB entry must be flushed as the valid PTE with the dirty bit clear 00068 // has been fetched into the TB. If it isn't flushed, another fault 00069 // is generated as the dirty bit is not set in the cached TB entry. 00070 // 00071 00072 // KiFlushSingleDataTb( FaultingAddress ); 00073 __dtbis( FaultingAddress ); 00074 00075 // 00076 // The page is NOT copy on write, update the PTE setting both the 00077 // dirty bit and the accessed bit. Note, that as this PTE is in 00078 // the TB, the TB must be flushed. 00079 // 00080 00081 PageFrameIndex = MI_GET_PAGE_FRAME_FROM_PTE(PointerPte); 00082 Pfn1 = MI_PFN_ELEMENT (PageFrameIndex); 00083 00084 TempPte = *PointerPte; 00085 TempPte.u.Hard.FaultOnWrite = 0; 00086 MI_SET_ACCESSED_IN_PTE (&TempPte, 1); 00087 *PointerPte = TempPte; 00088 00089 // 00090 // If the PFN database lock is not held, then do not update the 00091 // PFN database. 00092 // 00093 00094 if( PfnHeld ){ 00095 00096 // 00097 // Set the modified field in the PFN database, also, if the physical 00098 // page is currently in a paging file, free up the page file space 00099 // as the contents are now worthless. 00100 // 00101 00102 if ( (Pfn1->OriginalPte.u.Soft.Prototype == 0) && 00103 (Pfn1->u3.e1.WriteInProgress == 0) ) { 00104 00105 // 00106 // This page is in page file format, deallocate the page file space. 00107 // 00108 00109 MiReleasePageFileSpace (Pfn1->OriginalPte); 00110 00111 // 00112 // Change original PTE to indicate no page file space is reserved, 00113 // otherwise the space will be deallocated when the PTE is 00114 // deleted. 00115 // 00116 00117 Pfn1->OriginalPte.u.Soft.PageFileHigh = 0; 00118 } 00119 00120 Pfn1->u3.e1.Modified = 1; 00121 00122 } 00123 00124 00125 return; 00126 }