00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "mi.h"
00022
00023 #define MM_ZERO_PAGE_OBJECT 0
00024 #define PO_SYS_IDLE_OBJECT 1
00025 #define NUMBER_WAIT_OBJECTS 2
00026
00027
00028
VOID
00029 MmZeroPageThread (
00030 VOID
00031 )
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
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 }