Source code of Windows XP (NT5)
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.

126 lines
2.7 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Copyright (c) 1992 Digital Equipment Corporation
  4. Module Name:
  5. setdirty.c
  6. Abstract:
  7. This module contains the setting dirty bit routine for memory management.
  8. ALPHA specific.
  9. Author:
  10. Lou Perazzoli (loup) 10-Apr-1990.
  11. Joe Notarangelo 23-Apr-1992 ALPHA version
  12. Revision History:
  13. --*/
  14. #include "mi.h"
  15. VOID
  16. MiSetDirtyBit (
  17. IN PVOID FaultingAddress,
  18. IN PMMPTE PointerPte,
  19. IN ULONG PfnHeld
  20. )
  21. /*++
  22. Routine Description:
  23. This routine sets dirty in the specified PTE and the modify bit in the
  24. correpsonding PFN element. If any page file space is allocated, it
  25. is deallocated.
  26. Arguments:
  27. FaultingAddress - Supplies the faulting address.
  28. PointerPte - Supplies a pointer to the corresponding valid PTE.
  29. PfnHeld - Supplies TRUE if the PFN mutex is already held.
  30. Return Value:
  31. None.
  32. Environment:
  33. Kernel mode, APC's disabled, Working set mutex held.
  34. --*/
  35. {
  36. MMPTE TempPte;
  37. ULONG PageFrameIndex;
  38. PMMPFN Pfn1;
  39. KIRQL OldIrql;
  40. //
  41. // The TB entry must be flushed as the valid PTE with the dirty bit clear
  42. // has been fetched into the TB. If it isn't flushed, another fault
  43. // is generated as the dirty bit is not set in the cached TB entry.
  44. //
  45. // KiFlushSingleDataTb( FaultingAddress );
  46. __dtbis( FaultingAddress );
  47. //
  48. // The page is NOT copy on write, update the PTE setting both the
  49. // dirty bit and the accessed bit. Note, that as this PTE is in
  50. // the TB, the TB must be flushed.
  51. //
  52. PageFrameIndex = PointerPte->u.Hard.PageFrameNumber;
  53. Pfn1 = MI_PFN_ELEMENT (PageFrameIndex);
  54. TempPte = *PointerPte;
  55. TempPte.u.Hard.Dirty = 1;
  56. MI_SET_ACCESSED_IN_PTE (&TempPte, 1);
  57. *PointerPte = TempPte;
  58. //
  59. // If the PFN database lock is not held, then do not update the
  60. // PFN database.
  61. //
  62. if (PfnHeld) {
  63. //
  64. // Set the modified field in the PFN database, also, if the physical
  65. // page is currently in a paging file, free up the page file space
  66. // as the contents are now worthless.
  67. //
  68. if ( (Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
  69. (Pfn1->u3.e1.WriteInProgress == 0) ) {
  70. //
  71. // This page is in page file format, deallocate the page file space.
  72. //
  73. MiReleasePageFileSpace (Pfn1->OriginalPte);
  74. //
  75. // Change original PTE to indicate no page file space is reserved,
  76. // otherwise the space will be deallocated when the PTE is
  77. // deleted.
  78. //
  79. Pfn1->OriginalPte.u.Soft.PageFileHigh = 0;
  80. }
  81. Pfn1->u3.e1.Modified = 1;
  82. }
  83. return;
  84. }