diff options
Diffstat (limited to 'private/ntos/mm/i386/setmodfy.c')
-rw-r--r-- | private/ntos/mm/i386/setmodfy.c | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/private/ntos/mm/i386/setmodfy.c b/private/ntos/mm/i386/setmodfy.c new file mode 100644 index 000000000..e897ece48 --- /dev/null +++ b/private/ntos/mm/i386/setmodfy.c @@ -0,0 +1,242 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + setmodfy.c + +Abstract: + + This module contains the setting modify bit routine for memory management. + + i386 specific. + +Author: + + 10-Apr-1989 + +Revision History: + +--*/ + +#include "mi.h" + +VOID +MiSetModifyBit ( + IN PMMPFN Pfn + ) + +/*++ + +Routine Description: + + This routine sets the modify bit in the specified PFN element + and deallocates and allocated page file space. + +Arguments: + + Pfn - Supplies the pointer to the PFN element to update. + +Return Value: + + None. + +Environment: + + Kernel mode, APC's disabled, Working set mutex held and PFN mutex held. + +--*/ + +{ + + // + // Set the modified field in the PFN database, also, if the phyiscal + // page is currently in a paging file, free up the page file space + // as the contents are now worthless. + // + + Pfn->u3.e1.Modified = 1; + + if (Pfn->OriginalPte.u.Soft.Prototype == 0) { + + // + // This page is in page file format, deallocate the page file space. + // + + MiReleasePageFileSpace (Pfn->OriginalPte); + + // + // Change original PTE to indicate no page file space is reserved, + // otherwise the space will be deallocated when the PTE is + // deleted. + // + + Pfn->OriginalPte.u.Soft.PageFileHigh = 0; + } + + + return; +} + +ULONG +FASTCALL +MiDetermineUserGlobalPteMask ( + IN PMMPTE Pte + ) + +/*++ + +Routine Description: + + Builds a mask to OR with the PTE frame field. + This mask has the valid and access bits set and + has the global and owner bits set based on the + address of the PTE. + + ******************* NOTE ********************************************* + THIS ROUTINE DOES NOT CHECK FOR PDE'S WHICH NEED TO BE + SET GLOBAL AS IT ASSUMES ARE PDES FOR SYSTEM SPACE ARE + PROPERLY SET AT INITIALIZATION TIME! + +Arguments: + + Pte - Supplies a pointer to the PTE in which to fill. + +Return Value: + + Mask to OR into the frame to make a valid PTE. + +Environment: + + Kernel mode, 386 specific. + +--*/ + + +{ + MMPTE Mask; + + Mask.u.Long = 0; + Mask.u.Hard.Valid = 1; + Mask.u.Hard.Accessed = 1; + + if ((Pte) <= MiGetPteAddress(MM_HIGHEST_USER_ADDRESS)) { + Mask.u.Hard.Owner = 1; + } else if (((Pte) < MiGetPteAddress (PTE_BASE)) || + ((Pte) >= MiGetPteAddress (MM_SYSTEM_CACHE_WORKING_SET))) { + Mask.u.Hard.Global = MmPteGlobal; + } else if (((Pte) >= MiGetPdeAddress (NULL)) || + ((Pte) <= MiGetPdeAddress (MM_HIGHEST_USER_ADDRESS))) { + Mask.u.Hard.Owner = 1; + } + return Mask.u.Long; +} + + + + +#if !defined(NT_UP) + +ULONG MmSetDirtyCount; //fixfix remove + + +VOID +MiSetDirtyBit ( + IN PVOID FaultingAddress, + IN PMMPTE PointerPte, + IN ULONG PfnHeld + ) + +/*++ + +Routine Description: + + This routine sets dirty in the specified PTE and the modify bit in the + correpsonding PFN element. If any page file space is allocated, it + is deallocated. + +Arguments: + + FaultingAddress - Supplies the faulting address. + + PointerPte - Supplies a pointer to the corresponding valid PTE. + + PfnHeld - Supplies TRUE if the PFN mutex is already held. + +Return Value: + + None. + +Environment: + + Kernel mode, APC's disabled, Working set mutex held. + +--*/ + +{ + MMPTE TempPte; + ULONG PageFrameIndex; + PMMPFN Pfn1; + KIRQL OldIrql; + + // + // The page is NOT copy on write, update the PTE setting both the + // dirty bit and the accessed bit. Note, that as this PTE is in + // the TB, the TB must be flushed. + // + + MmSetDirtyCount += 1; //fixfix - remove + + TempPte = *PointerPte; + MI_SET_PTE_DIRTY (TempPte); + MI_SET_ACCESSED_IN_PTE (&TempPte, 1); + *PointerPte = TempPte; + + // + // Check state of PFN mutex and if not held, don't update PFN database. + // + + if (PfnHeld) { + + PageFrameIndex = PointerPte->u.Hard.PageFrameNumber; + Pfn1 = MI_PFN_ELEMENT (PageFrameIndex); + + // + // Set the modified field in the PFN database, also, if the phyiscal + // page is currently in a paging file, free up the page file space + // as the contents are now worthless. + // + + if ((Pfn1->OriginalPte.u.Soft.Prototype == 0) && + (Pfn1->u3.e1.WriteInProgress == 0)) { + + // + // This page is in page file format, deallocate the page file space. + // + + MiReleasePageFileSpace (Pfn1->OriginalPte); + + // + // Change original PTE to indicate no page file space is reserved, + // otherwise the space will be deallocated when the PTE is + // deleted. + // + + Pfn1->OriginalPte.u.Soft.PageFileHigh = 0; + } + + Pfn1->u3.e1.Modified = 1; + } + + // + // The TB entry must be flushed as the valid PTE with the dirty bit clear + // has been fetched into the TB. If it isn't flushed, another fault + // is generated as the dirty bit is not set in the cached TB entry. + // + + KeFillEntryTb ((PHARDWARE_PTE)PointerPte, FaultingAddress, TRUE); + return; +} +#endif + |