00035 :
00036
00037 Implements
the NT zeroing page thread. This thread runs
00038 at priority zero and removes a page from
the free list,
00039 zeroes
it, and places
it on
the zeroed page list.
00040
00041 Arguments:
00042
00043 StartContext - not used.
00044
00045 Return Value:
00046
00047 None.
00048
00049 Environment:
00050
00051 Kernel mode.
00052
00053 --*/
00054
00055 {
00056 PVOID EndVa;
00057 KIRQL OldIrql;
00058 PFN_NUMBER PageFrame;
00059
PMMPFN Pfn1;
00060 PVOID StartVa;
00061
PKTHREAD Thread;
00062 PVOID ZeroBase;
00063 PFN_NUMBER NewPage;
00064 PVOID WaitObjects[
NUMBER_WAIT_OBJECTS];
00065
NTSTATUS Status;
00066
00067
00068
00069
00070
00071
00072
#if !defined(_IA64_)
00073
MiFindInitializationCode (&StartVa, &EndVa);
00074
if (StartVa !=
NULL) {
00075
MiFreeInitializationCode (StartVa, EndVa);
00076 }
00077
#endif
00078
00079
00080
00081
00082
00083
00084
00085 Thread =
KeGetCurrentThread();
00086 Thread->
BasePriority = 0;
00087
KeSetPriorityThread (Thread, 0);
00088
00089
00090
00091
00092
00093 WaitObjects[
MM_ZERO_PAGE_OBJECT] = &
MmZeroingPageEvent;
00094 WaitObjects[
PO_SYS_IDLE_OBJECT] = &
PoSystemIdleTimer;
00095
00096
00097
00098
00099
00100
do {
00101
00102
00103
00104
00105
00106
00107
Status =
KeWaitForMultipleObjects (NUMBER_WAIT_OBJECTS,
00108 WaitObjects,
00109 WaitAny,
00110 WrFreePage,
00111 KernelMode,
00112 FALSE,
00113 (PLARGE_INTEGER) NULL,
00114 (
PKWAIT_BLOCK) NULL
00115 );
00116
00117
if (
Status ==
PO_SYS_IDLE_OBJECT) {
00118
PoSystemIdleWorker (TRUE);
00119
continue;
00120 }
00121
00122
LOCK_PFN_WITH_TRY (OldIrql);
00123
do {
00124
if ((
volatile)
MmFreePageListHead.
Total == 0) {
00125
00126
00127
00128
00129
00130
00131
MmZeroingPageThreadActive =
FALSE;
00132
UNLOCK_PFN (OldIrql);
00133
break;
00134
00135 }
else {
00136
00137 PageFrame =
MmFreePageListHead.
Flink;
00138 Pfn1 =
MI_PFN_ELEMENT(PageFrame);
00139
00140
ASSERT (PageFrame != MM_EMPTY_LIST);
00141 Pfn1 =
MI_PFN_ELEMENT(PageFrame);
00142
00143 NewPage =
MiRemoveAnyPage (MI_GET_SECONDARY_COLOR (PageFrame, Pfn1));
00144
if (NewPage != PageFrame) {
00145
00146
00147
00148
00149
00150
00151
KeBugCheckEx (PFN_LIST_CORRUPT,
00152 0x8F,
00153 NewPage,
00154 PageFrame,
00155 0);
00156 }
00157
00158
00159
00160
00161
00162
#if defined(_AXP64_) || defined(_X86_) || defined(_IA64_)
00163
00164 ZeroBase =
MiMapPageToZeroInHyperSpace (PageFrame);
00165
UNLOCK_PFN (OldIrql);
00166
00167
#if defined(_X86_)
00168
00169
KeZeroPageFromIdleThread(ZeroBase);
00170
00171
#else //X86
00172
00173 RtlZeroMemory (ZeroBase, PAGE_SIZE);
00174
00175
#endif //X86
00176
00177
#else //AXP64||X86||IA64
00178
00179 ZeroBase = (PVOID)(Pfn1->
u3.e1.PageColor <<
PAGE_SHIFT);
00180
UNLOCK_PFN (OldIrql);
00181 HalZeroPage(ZeroBase, ZeroBase, PageFrame);
00182
00183
#endif //AXP64||X86||IA64
00184
00185
LOCK_PFN_WITH_TRY (OldIrql);
00186
MiInsertPageInList (MmPageLocationList[ZeroedPageList],
00187 PageFrame);
00188 }
00189 }
while(
TRUE);
00190 }
while (
TRUE);
00191 }
}