00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include "mi.h"
00025
00026
VOID
00027
MiFeedSysPtePool (
00028 IN ULONG Index
00029 );
00030
00031
PMMPTE
00032
MiReserveSystemPtes2 (
00033 IN ULONG NumberOfPtes,
00034 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
00035 IN ULONG Alignment,
00036 IN ULONG Offset,
00037 IN ULONG BugCheckOnFailure
00038 );
00039
00040 ULONG
00041
MiGetSystemPteListCount (
00042 IN ULONG ListSize
00043 );
00044
00045
#ifdef ALLOC_PRAGMA
00046
#pragma alloc_text(INIT,MiInitializeSystemPtes)
00047
#pragma alloc_text(INIT,MiAddSystemPtes)
00048
#pragma alloc_text(MISYSPTE,MiReserveSystemPtes)
00049
#pragma alloc_text(MISYSPTE,MiReserveSystemPtes2)
00050
#pragma alloc_text(MISYSPTE,MiFeedSysPtePool)
00051
#pragma alloc_text(MISYSPTE,MiReleaseSystemPtes)
00052
#pragma alloc_text(MISYSPTE,MiGetSystemPteListCount)
00053
#endif
00054
00055
#ifdef _MI_GUARD_PTE_
00056
#define _MI_SYSPTE_DEBUG_ 1
00057
#endif
00058
00059
#ifdef _MI_SYSPTE_DEBUG_
00060
typedef struct _MMPTE_TRACKER {
00061
USHORT NumberOfPtes;
00062 BOOLEAN InUse;
00063 BOOLEAN Reserved;
00064 } MMPTE_TRACKER, *PMMPTE_TRACKER;
00065
00066 PMMPTE_TRACKER MiPteTracker;
00067
#endif
00068
00069 ULONG
MmTotalFreeSystemPtes[
MaximumPtePoolTypes];
00070 PMMPTE MmSystemPtesStart[
MaximumPtePoolTypes];
00071 PMMPTE MmSystemPtesEnd[
MaximumPtePoolTypes];
00072
00073 #define MM_MIN_SYSPTE_FREE 500
00074 #define MM_MAX_SYSPTE_FREE 3000
00075
00076 PMMPTE MmFlushPte1;
00077
00078 ULONG
MmFlushCounter;
00079
00080
00081
00082
00083
00084
#ifdef _ALPHA_
00085
00086
00087
00088
00089
00090 ULONG
MmSysPteIndex[
MM_SYS_PTE_TABLES_MAX] = {1,2,4,9,16};
00091
00092 UCHAR
MmSysPteTables[17] = {0,0,1,2,2,3,3,3,3,3,4,4,4,4,4,4,4};
00093
00094
#else
00095
00096 ULONG
MmSysPteIndex[
MM_SYS_PTE_TABLES_MAX] = {1,2,4,8,16};
00097
00098 UCHAR
MmSysPteTables[17] = {0,0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4};
00099
#endif
00100
00101 MMPTE MmFreeSysPteListBySize [
MM_SYS_PTE_TABLES_MAX];
00102 PMMPTE MmLastSysPteListBySize [
MM_SYS_PTE_TABLES_MAX];
00103 ULONG
MmSysPteListBySizeCount [
MM_SYS_PTE_TABLES_MAX];
00104 ULONG
MmSysPteMinimumFree [
MM_SYS_PTE_TABLES_MAX] = {100,50,30,20,20};
00105
00106
00107
00108
00109
00110 #define MM_PTE_LIST_1 400
00111 #define MM_PTE_LIST_2 100
00112 #define MM_PTE_LIST_4 60
00113 #define MM_PTE_LIST_8 50
00114 #define MM_PTE_LIST_16 40
00115
00116 #define MM_PTE_TABLE_LIMIT 16
00117
00118
PMMPTE
00119
MiReserveSystemPtes2 (
00120 IN ULONG NumberOfPtes,
00121 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
00122 IN ULONG Alignment,
00123 IN ULONG Offset,
00124 IN ULONG BugCheckOnFailure
00125 );
00126
00127
VOID
00128
MiFeedSysPtePool (
00129 IN ULONG Index
00130 );
00131
00132
VOID
00133
MiDumpSystemPtes (
00134 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
00135 );
00136
00137 ULONG
00138
MiCountFreeSystemPtes (
00139 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
00140 );
00141
00142 PVOID
00143
MiGetHighestPteConsumer (
00144 OUT PULONG_PTR NumberOfPtes
00145 );
00146
00147
#ifdef _MI_SYSPTE_DEBUG_
00148
ULONG MiPtesChecked[0x10];
00149
00150
00151
VOID
00152 MiValidateSystemPtes (
00153 IN
PMMPTE StartingPte,
00154 IN ULONG NumberOfPtes
00155 )
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 {
00182 KIRQL OldIrql;
00183 ULONG
Index;
00184
PMMPTE EndingPte;
00185
PMMPTE PointerPte1;
00186
PMMPTE PointerFreedPte;
00187 ULONG PtesInThisBucket;
00188 ULONG j;
00189
00190
ASSERT (NumberOfPtes != 0);
00191
00192 EndingPte = StartingPte + NumberOfPtes - 1;
00193
00194
MiLockSystemSpace(OldIrql);
00195
00196
for (
Index = 0;
Index <
MM_SYS_PTE_TABLES_MAX;
Index += 1) {
00197
00198 PointerPte1 = &
MmFreeSysPteListBySize[
Index];
00199
00200
while (PointerPte1->
u.List.NextEntry !=
MM_EMPTY_PTE_LIST) {
00201
00202 MiPtesChecked[0] += 1;
00203
00204 PointerPte1 =
MmSystemPteBase + PointerPte1->
u.List.NextEntry;
00205
00206 PtesInThisBucket =
MmSysPteIndex[
Index];
00207
00208
if (StartingPte >= PointerPte1 && StartingPte < PointerPte1 + PtesInThisBucket) {
00209
DbgPrint(
"MiValidateSystemPtes1: %x %x %x %x %x %x\n",
00210 StartingPte,
00211 EndingPte,
00212 NumberOfPtes,
00213 PointerPte1,
00214 PtesInThisBucket,
00215 Index);
00216 DbgBreakPoint ();
00217 }
00218
00219
if (EndingPte >= PointerPte1 && EndingPte < PointerPte1 + PtesInThisBucket) {
00220
DbgPrint(
"MiValidateSystemPtes2: %x %x %x %x %x %x\n",
00221 StartingPte,
00222 EndingPte,
00223 NumberOfPtes,
00224 PointerPte1,
00225 PtesInThisBucket,
00226 Index);
00227 DbgBreakPoint ();
00228 }
00229
00230
if (StartingPte < PointerPte1 && EndingPte >= PointerPte1 + PtesInThisBucket) {
00231
DbgPrint(
"MiValidateSystemPtes3: %x %x %x %x %x %x\n",
00232 StartingPte,
00233 EndingPte,
00234 NumberOfPtes,
00235 PointerPte1,
00236 PtesInThisBucket,
00237 Index);
00238 DbgBreakPoint ();
00239 }
00240
00241 PointerFreedPte = PointerPte1;
00242
for (j = 0; j <
MmSysPteIndex[
Index]; j++) {
00243
ASSERT (PointerFreedPte->
u.Hard.Valid == 0);
00244 PointerFreedPte += 1;
00245 MiPtesChecked[1] += 1;
00246 }
00247 }
00248 }
00249
00250
MiUnlockSystemSpace(OldIrql);
00251 }
00252
00253
00254
VOID
00255 MiCheckPteAllocation (
00256 IN
PMMPTE StartingPte,
00257 IN ULONG NumberOfPtes,
00258 IN ULONG CallerId,
00259 IN ULONG Context1
00260 )
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 {
00290 ULONG i;
00291 ULONG_PTR
Index;
00292
PMMPTE BasePte;
00293 PMMPTE_TRACKER Tracker;
00294
00295
00296
00297
00298
00299
if (StartingPte <
MmSystemPtesStart[
SystemPteSpace] ||
00300 StartingPte + NumberOfPtes >
MmSystemPtesEnd[
SystemPteSpace] + 1) {
00301
return;
00302 }
00303
00304
if (MiPteTracker ==
NULL) {
00305
return;
00306 }
00307
00308
Index = StartingPte -
MmSystemPtesStart[
SystemPteSpace];
00309
00310 Tracker = &MiPteTracker[
Index];
00311
00312
for (i = 0; i < NumberOfPtes; i += 1) {
00313
00314
if (Tracker->InUse ==
TRUE) {
00315
KeBugCheckEx (SYSTEM_PTE_MISUSE,
00316 7,
00317 (ULONG_PTR)StartingPte,
00318 NumberOfPtes,
00319 CallerId);
00320 }
00321
00322 Tracker += 1;
00323 }
00324
00325 Tracker = &MiPteTracker[
Index];
00326
00327
ASSERT (NumberOfPtes < 0x10000);
00328
00329 Tracker->NumberOfPtes = (
USHORT)NumberOfPtes;
00330
00331
for (i = 0; i < NumberOfPtes; i += 1) {
00332 Tracker->InUse =
TRUE;
00333 Tracker += 1;
00334 }
00335
00336 MiPtesChecked[0xE] += 1;
00337 }
00338
00339
00340
VOID
00341 MiCheckPteRelease (
00342 IN
PMMPTE StartingPte,
00343 IN ULONG NumberOfPtes
00344 )
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 {
00370 ULONG i;
00371 ULONG_PTR
Index;
00372
PMMPTE BasePte;
00373 PMMPTE_TRACKER Tracker;
00374
00375
00376
00377
00378
00379
if (StartingPte <
MmSystemPtesStart[
SystemPteSpace] ||
00380 StartingPte + NumberOfPtes >
MmSystemPtesEnd[
SystemPteSpace] + 1) {
00381
return;
00382 }
00383
00384
if (MiPteTracker ==
NULL) {
00385
return;
00386 }
00387
00388
ASSERT (NumberOfPtes < 0x10000);
00389
00390
Index = StartingPte -
MmSystemPtesStart[
SystemPteSpace];
00391
00392 Tracker = &MiPteTracker[
Index];
00393
00394
if ((NumberOfPtes == 0) ||
00395 (Tracker->NumberOfPtes != NumberOfPtes)) {
00396
KeBugCheckEx (SYSTEM_PTE_MISUSE,
00397 8,
00398 (ULONG_PTR)StartingPte,
00399 NumberOfPtes,
00400 Tracker->NumberOfPtes);
00401 }
00402
00403 Tracker->NumberOfPtes = 0;
00404
00405
for (i = 0; i < NumberOfPtes; i += 1) {
00406
00407
if (Tracker->InUse ==
FALSE) {
00408
KeBugCheckEx (SYSTEM_PTE_MISUSE,
00409 9,
00410 (ULONG_PTR)StartingPte,
00411 NumberOfPtes,
00412 i);
00413 }
00414
00415 Tracker += 1;
00416 }
00417
00418 Tracker = &MiPteTracker[
Index];
00419
00420
for (i = 0; i < NumberOfPtes; i += 1) {
00421 Tracker->InUse =
FALSE;
00422 Tracker += 1;
00423 }
00424
00425 MiPtesChecked[0xF] += 1;
00426 }
00427
00428
00429
VOID
00430 MiRebuildPteTracker (
00431 IN
PMMPTE StartingPte,
00432 IN ULONG NumberOfPtes
00433 )
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 {
00464 KIRQL OldIrql;
00465 ULONG_PTR OldPtes;
00466 ULONG_PTR NewPtes;
00467 PMMPTE_TRACKER OldTracker;
00468 PMMPTE_TRACKER NewTracker;
00469
00470
00471
00472
00473
00474
if (MiPteTracker == (PMMPTE_TRACKER) 0) {
00475
return;
00476 }
00477
00478
if (StartingPte + NumberOfPtes !=
MmSystemPtesStart[
SystemPteSpace]) {
00479
#if 0
00480
MiFreePoolPages ((PVOID)MiPteTracker);
00481
#endif
00482
MiPteTracker = (PMMPTE_TRACKER) 0;
00483
return;
00484 }
00485
00486
if (MiPteTracker) {
00487 OldPtes =
MmSystemPtesEnd[
SystemPteSpace] -
MmSystemPtesStart[
SystemPteSpace] + 1;
00488
00489 NewPtes = OldPtes + NumberOfPtes;
00490
00491 NewTracker = (PMMPTE_TRACKER)
ExAllocatePoolWithTag (
00492 NonPagedPool,
00493 (ULONG_PTR)(NewPtes *
sizeof (MMPTE_TRACKER)),
00494 ' mM');
00495
00496
if (NewTracker == (PMMPTE_TRACKER) 0) {
00497 MiPteTracker = (PMMPTE_TRACKER) 0;
00498
return;
00499 }
00500
00501 RtlZeroMemory (NewTracker, NewPtes *
sizeof (MMPTE_TRACKER));
00502
00503 OldTracker = MiPteTracker;
00504
00505
MiLockSystemSpace(OldIrql);
00506
00507 RtlCopyMemory (NewTracker + NumberOfPtes, OldTracker, OldPtes *
sizeof (MMPTE_TRACKER));
00508
00509 MiPteTracker = NewTracker;
00510
00511
MiUnlockSystemSpace(OldIrql);
00512
00513
#if 0
00514
MiFreePoolPages ((PVOID)OldTracker);
00515
#endif
00516
00517 MiPtesChecked[0xD] += 1;
00518 }
00519 }
00520
#endif
00521
00522
00523
PMMPTE
00524 MiReserveSystemPtes (
00525 IN ULONG NumberOfPtes,
00526 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
00527 IN ULONG Alignment,
00528 IN ULONG Offset,
00529 IN ULONG BugCheckOnFailure
00530 )
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 {
00571
PMMPTE PointerPte;
00572
PMMPTE Previous;
00573 KIRQL OldIrql;
00574 ULONG PteMask;
00575 ULONG MaskSize;
00576 ULONG
Index;
00577
00578
#ifdef _MI_GUARD_PTE_
00579
ULONG ExactPtes;
00580
00581
if (NumberOfPtes == 0) {
00582
KeBugCheckEx (SYSTEM_PTE_MISUSE,
00583 0xA,
00584 BugCheckOnFailure,
00585 NumberOfPtes,
00586 SystemPtePoolType);
00587 }
00588
00589
if (SystemPtePoolType ==
SystemPteSpace) {
00590 NumberOfPtes += 1;
00591 }
00592
00593 ExactPtes = NumberOfPtes;
00594
#endif
00595
00596
if (SystemPtePoolType ==
SystemPteSpace) {
00597
00598 MaskSize = (Alignment - 1) >> (
PAGE_SHIFT -
PTE_SHIFT);
00599 PteMask = MaskSize & (
Offset >> (
PAGE_SHIFT -
PTE_SHIFT));
00600
00601
00602
00603
00604
00605
00606
MiLockSystemSpace(OldIrql);
00607
00608
if (NumberOfPtes <=
MM_PTE_TABLE_LIMIT) {
00609
Index =
MmSysPteTables [NumberOfPtes];
00610
ASSERT (NumberOfPtes <=
MmSysPteIndex[
Index]);
00611 PointerPte = &
MmFreeSysPteListBySize[
Index];
00612
#if DBG
00613
if (MmDebug &
MM_DBG_SYS_PTES) {
00614
PMMPTE PointerPte1;
00615 PointerPte1 = &
MmFreeSysPteListBySize[
Index];
00616
while (PointerPte1->
u.List.NextEntry !=
MM_EMPTY_PTE_LIST) {
00617
PMMPTE PointerFreedPte;
00618 ULONG j;
00619
00620 PointerPte1 =
MmSystemPteBase + PointerPte1->
u.List.NextEntry;
00621 PointerFreedPte = PointerPte1;
00622
for (j = 0; j <
MmSysPteIndex[
Index]; j++) {
00623
ASSERT (PointerFreedPte->
u.Hard.Valid == 0);
00624 PointerFreedPte++;
00625 }
00626 }
00627 }
00628
#endif //DBG
00629
00630 Previous = PointerPte;
00631
00632
while (PointerPte->u.List.NextEntry !=
MM_EMPTY_PTE_LIST) {
00633
00634
00635
00636
00637
00638 Previous = PointerPte;
00639 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
00640
#if !defined(_IA64_)
00641
if (PointerPte ==
MmFlushPte1) {
00642
KeFlushEntireTb (
TRUE,
TRUE);
00643
MmFlushCounter = (
MmFlushCounter + 1) &
MM_FLUSH_COUNTER_MASK;
00644
MmFlushPte1 =
NULL;
00645 }
00646
#endif
00647
if ((Alignment == 0) ||
00648 (((ULONG_PTR)PointerPte & MaskSize) == PteMask)) {
00649
00650
#ifdef _MI_SYSPTE_DEBUG_
00651
MiCheckPteAllocation (PointerPte,
00652 NumberOfPtes,
00653 0,
00654
MmSysPteIndex[
Index]);
00655
#endif
00656
00657
00658
00659
00660
ASSERT ((PointerPte->u.List.NextEntry +
MmSystemPteBase) >=
00661
MmSystemPtesStart[SystemPtePoolType] ||
00662 PointerPte->u.List.NextEntry ==
MM_EMPTY_PTE_LIST);
00663
ASSERT ((PointerPte->u.List.NextEntry +
MmSystemPteBase) <=
00664
MmSystemPtesEnd[SystemPtePoolType] ||
00665 PointerPte->u.List.NextEntry ==
MM_EMPTY_PTE_LIST);
00666
00667 Previous->
u.List.NextEntry = PointerPte->u.List.NextEntry;
00668
MmSysPteListBySizeCount [
Index] -= 1;
00669
00670
#if !defined(_IA64_)
00671
if (NumberOfPtes != 1) {
00672
00673
00674
00675
00676
00677
if ((PointerPte + 1)->u.List.NextEntry ==
MmFlushCounter) {
00678
KeFlushEntireTb (
TRUE,
TRUE);
00679
MmFlushCounter = (
MmFlushCounter + 1) &
00680
MM_FLUSH_COUNTER_MASK;
00681
MmFlushPte1 =
NULL;
00682 }
00683 }
00684
#endif
00685
if (PointerPte->u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
00686
MmLastSysPteListBySize[
Index] = Previous;
00687 }
00688
#if DBG
00689
00690
if (MmDebug &
MM_DBG_SYS_PTES) {
00691
PMMPTE PointerPte1;
00692 PointerPte1 = &
MmFreeSysPteListBySize[
Index];
00693
while (PointerPte1->
u.List.NextEntry !=
MM_EMPTY_PTE_LIST) {
00694
PMMPTE PointerFreedPte;
00695 ULONG j;
00696
00697 PointerPte1 =
MmSystemPteBase + PointerPte1->
u.List.NextEntry;
00698 PointerFreedPte = PointerPte1;
00699
for (j = 0; j <
MmSysPteIndex[
Index]; j++) {
00700
ASSERT (PointerFreedPte->
u.Hard.Valid == 0);
00701 PointerFreedPte++;
00702 }
00703 }
00704 }
00705
#endif //DBG
00706
MiUnlockSystemSpace(OldIrql);
00707
00708
#if DBG
00709
PointerPte->u.List.NextEntry = 0xABCDE;
00710
if (MmDebug &
MM_DBG_SYS_PTES) {
00711
00712
PMMPTE PointerFreedPte;
00713 ULONG j;
00714
00715 PointerFreedPte = PointerPte;
00716
for (j = 0; j <
MmSysPteIndex[
Index]; j++) {
00717
ASSERT (PointerFreedPte->
u.Hard.Valid == 0);
00718 PointerFreedPte++;
00719 }
00720 }
00721
if (PointerPte <
MmSystemPtesStart[SystemPtePoolType]) {
00722
KeBugCheckEx (SYSTEM_PTE_MISUSE,
00723 0xB,
00724 (ULONG_PTR)PointerPte,
00725 NumberOfPtes,
00726 SystemPtePoolType);
00727 }
00728
if (PointerPte >
MmSystemPtesEnd[SystemPtePoolType]) {
00729
KeBugCheckEx (SYSTEM_PTE_MISUSE,
00730 0xC,
00731 (ULONG_PTR)PointerPte,
00732 NumberOfPtes,
00733 SystemPtePoolType);
00734 }
00735
#endif //DBG
00736
00737
if (
MmSysPteListBySizeCount[
Index] <
00738
MmSysPteMinimumFree[
Index]) {
00739
MiFeedSysPtePool (
Index);
00740 }
00741
#ifdef _MI_GUARD_PTE_
00742
(PointerPte + ExactPtes - 1)->u.Long =
MM_KERNEL_NOACCESS_PTE;
00743
#endif
00744
return PointerPte;
00745 }
00746 }
00747 NumberOfPtes =
MmSysPteIndex [
Index];
00748 }
00749
MiUnlockSystemSpace(OldIrql);
00750 }
00751
00752
#ifdef _MI_GUARD_PTE_
00753
NumberOfPtes = ExactPtes;
00754
#endif
00755
00756 PointerPte =
MiReserveSystemPtes2 (NumberOfPtes,
00757 SystemPtePoolType,
00758 Alignment,
00759
Offset,
00760 BugCheckOnFailure);
00761
00762
#if DBG
00763
if (MmDebug &
MM_DBG_SYS_PTES) {
00764
00765
PMMPTE PointerFreedPte;
00766 ULONG j;
00767
00768
if (PointerPte) {
00769 PointerFreedPte = PointerPte;
00770
for (j = 0; j < NumberOfPtes; j++) {
00771
ASSERT (PointerFreedPte->
u.Hard.Valid == 0);
00772 PointerFreedPte++;
00773 }
00774 }
00775 }
00776
#endif //DBG
00777
00778
#ifdef _MI_GUARD_PTE_
00779
if (PointerPte) {
00780 (PointerPte + ExactPtes - 1)->
u.Long =
MM_KERNEL_NOACCESS_PTE;
00781 }
00782
#endif
00783
00784
return PointerPte;
00785 }
00786
00787
VOID
00788 MiFeedSysPtePool (
00789 IN ULONG Index
00790 )
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813 {
00814
#ifdef _MI_GUARD_PTE_
00815
UNREFERENCED_PARAMETER (
Index);
00816
#else
00817
ULONG i;
00818
PMMPTE PointerPte;
00819
00820
if (
MmTotalFreeSystemPtes[
SystemPteSpace] <
MM_MIN_SYSPTE_FREE) {
00821
return;
00822 }
00823
00824
for (i = 0; i < 10 ; i++ ) {
00825 PointerPte =
MiReserveSystemPtes2 (
MmSysPteIndex [
Index],
00826
SystemPteSpace,
00827 0,
00828 0,
00829
FALSE);
00830
if (PointerPte ==
NULL) {
00831
return;
00832 }
00833
MiReleaseSystemPtes (PointerPte,
00834
MmSysPteIndex [
Index],
00835
SystemPteSpace);
00836 }
00837
#endif
00838
return;
00839 }
00840
00841
00842
PMMPTE
00843 MiReserveSystemPtes2 (
00844 IN ULONG NumberOfPtes,
00845 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType,
00846 IN ULONG Alignment,
00847 IN ULONG Offset,
00848 IN ULONG BugCheckOnFailure
00849 )
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 {
00890
PMMPTE PointerPte;
00891
PMMPTE PointerFollowingPte;
00892
PMMPTE Previous;
00893 ULONG_PTR SizeInSet;
00894 KIRQL OldIrql;
00895 ULONG MaskSize;
00896 ULONG NumberOfRequiredPtes;
00897 ULONG OffsetSum;
00898 ULONG PtesToObtainAlignment;
00899
PMMPTE NextSetPointer;
00900 ULONG_PTR LeftInSet;
00901 ULONG_PTR PteOffset;
00902
MMPTE_FLUSH_LIST PteFlushList;
00903 PVOID HighConsumer;
00904 ULONG_PTR HighPteUse;
00905
00906 MaskSize = (Alignment - 1) >> (
PAGE_SHIFT -
PTE_SHIFT);
00907
00908 OffsetSum = (
Offset >> (
PAGE_SHIFT -
PTE_SHIFT)) |
00909 (Alignment >> (
PAGE_SHIFT -
PTE_SHIFT));
00910
00911
MiLockSystemSpace(OldIrql);
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 PointerPte = &
MmFirstFreeSystemPte[SystemPtePoolType];
00950 Previous = PointerPte;
00951
00952
if (PointerPte->u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
00953
00954
00955
00956
00957
00958
if (BugCheckOnFailure) {
00959
goto IssueBugcheck;
00960 }
00961
00962
MiUnlockSystemSpace(OldIrql);
00963
return NULL;
00964 }
00965
00966 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
00967
00968
if (Alignment <=
PAGE_SIZE) {
00969
00970
00971
00972
00973
00974
while (
TRUE) {
00975
00976
if (PointerPte->u.List.OneEntry) {
00977 SizeInSet = 1;
00978
00979 }
else {
00980
00981 PointerFollowingPte = PointerPte + 1;
00982 SizeInSet = (ULONG_PTR) PointerFollowingPte->
u.List.NextEntry;
00983 }
00984
00985
if (NumberOfPtes < SizeInSet) {
00986
00987
00988
00989
00990
00991
00992
if ((SizeInSet - NumberOfPtes) == 1) {
00993
00994
00995
00996
00997
00998 PointerPte->u.List.OneEntry = 1;
00999
01000 }
else {
01001
01002 PointerFollowingPte->
u.List.NextEntry = SizeInSet - NumberOfPtes;
01003
01004
01005
01006
01007
01008
#if 0
01009
if (MmDebug &
MM_DBG_SYS_PTES) {
01010
MiDumpSystemPtes(SystemPtePoolType);
01011 PointerFollowingPte = PointerPte + (SizeInSet - NumberOfPtes);
01012
DbgPrint(
"allocated 0x%lx Ptes at %lx\n",NumberOfPtes,PointerFollowingPte);
01013 }
01014
#endif //0
01015
}
01016
01017
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
01018
#if DBG
01019
if (MmDebug &
MM_DBG_SYS_PTES) {
01020
ASSERT (
MmTotalFreeSystemPtes[SystemPtePoolType] ==
01021
MiCountFreeSystemPtes (SystemPtePoolType));
01022 }
01023
#endif //DBG
01024
01025
#ifdef _MI_SYSPTE_DEBUG_
01026
MiCheckPteAllocation (PointerPte + (SizeInSet - NumberOfPtes),
01027 NumberOfPtes,
01028 1,
01029 0);
01030
#endif
01031
01032
MiUnlockSystemSpace(OldIrql);
01033
01034 PointerPte = PointerPte + (SizeInSet - NumberOfPtes);
01035
goto Flush;
01036 }
01037
01038
if (NumberOfPtes == SizeInSet) {
01039
01040
01041
01042
01043
01044
01045 Previous->
u.List.NextEntry = PointerPte->u.List.NextEntry;
01046
01047
01048
01049
01050
01051
#if 0
01052
if (MmDebug &
MM_DBG_SYS_PTES) {
01053
MiDumpSystemPtes(SystemPtePoolType);
01054 PointerFollowingPte = PointerPte + (SizeInSet - NumberOfPtes);
01055
DbgPrint(
"allocated 0x%lx Ptes at %lx\n",NumberOfPtes,PointerFollowingPte);
01056 }
01057
#endif //0
01058
01059
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
01060
#if DBG
01061
if (MmDebug &
MM_DBG_SYS_PTES) {
01062
ASSERT (
MmTotalFreeSystemPtes[SystemPtePoolType] ==
01063
MiCountFreeSystemPtes (SystemPtePoolType));
01064 }
01065
#endif //DBG
01066
01067
#ifdef _MI_SYSPTE_DEBUG_
01068
MiCheckPteAllocation (PointerPte,
01069 NumberOfPtes,
01070 2,
01071 0);
01072
#endif
01073
01074
MiUnlockSystemSpace(OldIrql);
01075
goto Flush;
01076 }
01077
01078
01079
01080
01081
01082
if (PointerPte->u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
01083
01084
01085
01086
01087
01088
if (BugCheckOnFailure) {
01089
goto IssueBugcheck;
01090 }
01091
01092
MiUnlockSystemSpace(OldIrql);
01093
return NULL;
01094 }
01095 Previous = PointerPte;
01096 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
01097
ASSERT (PointerPte > Previous);
01098 }
01099
01100 }
else {
01101
01102
01103
01104
01105
01106
while (
TRUE) {
01107
01108
if (PointerPte->u.List.OneEntry) {
01109 SizeInSet = 1;
01110
01111 }
else {
01112
01113 PointerFollowingPte = PointerPte + 1;
01114 SizeInSet = (ULONG_PTR) PointerFollowingPte->
u.List.NextEntry;
01115 }
01116
01117 PtesToObtainAlignment = (ULONG)
01118 (((OffsetSum - ((ULONG_PTR)PointerPte & MaskSize)) & MaskSize) >>
01119
PTE_SHIFT);
01120
01121 NumberOfRequiredPtes = NumberOfPtes + PtesToObtainAlignment;
01122
01123
if (NumberOfRequiredPtes < SizeInSet) {
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138 LeftInSet = SizeInSet - NumberOfRequiredPtes;
01139
01140
01141
01142
01143
01144 NextSetPointer = PointerPte + NumberOfRequiredPtes;
01145 NextSetPointer->
u.List.NextEntry =
01146 PointerPte->u.List.NextEntry;
01147
01148 PteOffset = (ULONG_PTR)(NextSetPointer -
MmSystemPteBase);
01149
01150
if (PtesToObtainAlignment == 0) {
01151
01152 Previous->
u.List.NextEntry += NumberOfRequiredPtes;
01153
01154 }
else {
01155
01156
01157
01158
01159
01160
01161 PointerPte->u.List.NextEntry = PteOffset;
01162
01163
01164
01165
01166
01167
if (PtesToObtainAlignment == 1) {
01168
01169
01170
01171
01172
01173 PointerPte->u.List.OneEntry = 1;
01174
01175 }
else {
01176
01177
01178
01179
01180
01181 PointerFollowingPte->
u.List.NextEntry =
01182 PtesToObtainAlignment;
01183 }
01184 }
01185
01186
01187
01188
01189
01190
if (LeftInSet == 1) {
01191 NextSetPointer->
u.List.OneEntry = 1;
01192 }
else {
01193 NextSetPointer->
u.List.OneEntry = 0;
01194 NextSetPointer += 1;
01195 NextSetPointer->
u.List.NextEntry = LeftInSet;
01196 }
01197
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
01198
#if DBG
01199
if (MmDebug &
MM_DBG_SYS_PTES) {
01200
ASSERT (
MmTotalFreeSystemPtes[SystemPtePoolType] ==
01201
MiCountFreeSystemPtes (SystemPtePoolType));
01202 }
01203
#endif //DBG
01204
01205
#ifdef _MI_SYSPTE_DEBUG_
01206
MiCheckPteAllocation (PointerPte + PtesToObtainAlignment,
01207 NumberOfPtes,
01208 3,
01209 0);
01210
#endif
01211
01212
MiUnlockSystemSpace(OldIrql);
01213
01214 PointerPte = PointerPte + PtesToObtainAlignment;
01215
goto Flush;
01216 }
01217
01218
if (NumberOfRequiredPtes == SizeInSet) {
01219
01220
01221
01222
01223
01224
01225
if (PtesToObtainAlignment == 0) {
01226
01227
01228
01229
01230
01231 Previous->
u.List.NextEntry =
01232 PointerPte->u.List.NextEntry;
01233
01234 }
else {
01235
01236
01237
01238
01239
01240
if (PtesToObtainAlignment == 1) {
01241
01242
01243
01244
01245
01246 PointerPte->u.List.OneEntry = 1;
01247
01248 }
else {
01249 PointerFollowingPte->
u.List.NextEntry =
01250 PtesToObtainAlignment;
01251
01252 }
01253 }
01254
01255
MmTotalFreeSystemPtes[SystemPtePoolType] -= NumberOfPtes;
01256
#if DBG
01257
if (MmDebug &
MM_DBG_SYS_PTES) {
01258
ASSERT (
MmTotalFreeSystemPtes[SystemPtePoolType] ==
01259
MiCountFreeSystemPtes (SystemPtePoolType));
01260 }
01261
#endif //DBG
01262
01263
#ifdef _MI_SYSPTE_DEBUG_
01264
MiCheckPteAllocation (PointerPte + PtesToObtainAlignment,
01265 NumberOfPtes,
01266 4,
01267 0);
01268
#endif
01269
01270
MiUnlockSystemSpace(OldIrql);
01271
01272 PointerPte = PointerPte + PtesToObtainAlignment;
01273
goto Flush;
01274 }
01275
01276
01277
01278
01279
01280
if (PointerPte->u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
01281
01282
01283
01284
01285
01286
if (BugCheckOnFailure) {
01287
goto IssueBugcheck;
01288 }
01289
01290
MiUnlockSystemSpace(OldIrql);
01291
return NULL;
01292 }
01293 Previous = PointerPte;
01294 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
01295
ASSERT (PointerPte > Previous);
01296 }
01297 }
01298 Flush:
01299
01300
if (SystemPtePoolType ==
SystemPteSpace) {
01301 PVOID BaseAddress;
01302 ULONG j;
01303
01304 PteFlushList.
Count = 0;
01305 Previous = PointerPte;
01306 BaseAddress =
MiGetVirtualAddressMappedByPte (Previous);
01307
01308
for (j = 0; j < NumberOfPtes ; j++) {
01309
if (PteFlushList.
Count !=
MM_MAXIMUM_FLUSH_COUNT) {
01310 PteFlushList.
FlushPte[PteFlushList.
Count] = Previous;
01311 PteFlushList.
FlushVa[PteFlushList.
Count] = BaseAddress;
01312 PteFlushList.
Count += 1;
01313 }
01314
01315
01316
01317
01318
ASSERT (Previous->
u.Hard.Valid == 0);
01319
01320 *Previous =
ZeroKernelPte;
01321 BaseAddress = (PVOID)((PCHAR)BaseAddress +
PAGE_SIZE);
01322 Previous++;
01323 }
01324
01325
KeRaiseIrql (
DISPATCH_LEVEL, &OldIrql);
01326
MiFlushPteList (&PteFlushList,
TRUE,
ZeroKernelPte);
01327
KeLowerIrql (OldIrql);
01328 }
01329
return PointerPte;
01330
01331 IssueBugcheck:
01332
01333
if (SystemPtePoolType ==
SystemPteSpace) {
01334
01335 HighConsumer =
MiGetHighestPteConsumer (&HighPteUse);
01336
01337
if (HighConsumer !=
NULL) {
01338
KeBugCheckEx (DRIVER_USED_EXCESSIVE_PTES,
01339 (ULONG_PTR)HighConsumer,
01340 HighPteUse,
01341
MmTotalFreeSystemPtes[SystemPtePoolType],
01342
MmNumberOfSystemPtes);
01343 }
01344 }
01345
01346
KeBugCheckEx (NO_MORE_SYSTEM_PTES,
01347 (ULONG_PTR)SystemPtePoolType,
01348 NumberOfPtes,
01349
MmTotalFreeSystemPtes[SystemPtePoolType],
01350
MmNumberOfSystemPtes);
01351 }
01352
01353
VOID
01354 MiReleaseSystemPtes (
01355 IN
PMMPTE StartingPte,
01356 IN ULONG NumberOfPtes,
01357 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
01358 )
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389 {
01390 ULONG_PTR
Size;
01391 ULONG i;
01392 ULONG_PTR PteOffset;
01393
PMMPTE PointerPte;
01394
PMMPTE PointerFollowingPte;
01395
PMMPTE NextPte;
01396 KIRQL OldIrql;
01397 ULONG
Index;
01398
#if defined(_IA64_)
01399
MMPTE_FLUSH_LIST PteFlushList;
01400
PMMPTE Previous;
01401 PVOID BaseAddress;
01402
#endif
01403
01404
01405
01406
01407
01408
ASSERT (NumberOfPtes != 0);
01409
01410
#ifdef _MI_GUARD_PTE_
01411
if (NumberOfPtes == 0) {
01412
KeBugCheckEx (SYSTEM_PTE_MISUSE,
01413 0xD,
01414 (ULONG_PTR)StartingPte,
01415 NumberOfPtes,
01416 SystemPtePoolType);
01417 }
01418
01419
if (SystemPtePoolType ==
SystemPteSpace) {
01420
if ((StartingPte + NumberOfPtes)->u.Long !=
MM_KERNEL_NOACCESS_PTE) {
01421
KeBugCheckEx (SYSTEM_PTE_MISUSE,
01422 0xE,
01423 (ULONG_PTR)StartingPte,
01424 NumberOfPtes,
01425 SystemPtePoolType);
01426 }
01427 NumberOfPtes += 1;
01428 }
01429
#endif
01430
01431
#if DBG
01432
if (StartingPte <
MmSystemPtesStart[SystemPtePoolType]) {
01433
KeBugCheckEx (SYSTEM_PTE_MISUSE,
01434 0xF,
01435 (ULONG_PTR)StartingPte,
01436 NumberOfPtes,
01437 SystemPtePoolType);
01438 }
01439
01440
if (StartingPte >
MmSystemPtesEnd[SystemPtePoolType]) {
01441
KeBugCheckEx (SYSTEM_PTE_MISUSE,
01442 0x10,
01443 (ULONG_PTR)StartingPte,
01444 NumberOfPtes,
01445 SystemPtePoolType);
01446 }
01447
#endif //DBG
01448
01449
#if 0
01450
if (MmDebug &
MM_DBG_SYS_PTES) {
01451
DbgPrint(
"releasing 0x%lx system PTEs at location %lx\n",NumberOfPtes,StartingPte);
01452 }
01453
#endif //0
01454
01455
#if defined(_IA64_)
01456
01457 PteFlushList.
Count = 0;
01458 Previous = StartingPte;
01459 BaseAddress =
MiGetVirtualAddressMappedByPte (Previous);
01460
for (i = 0; i < NumberOfPtes ; i++) {
01461
if (PteFlushList.
Count !=
MM_MAXIMUM_FLUSH_COUNT) {
01462 PteFlushList.
FlushPte[PteFlushList.
Count] = Previous;
01463 PteFlushList.
FlushVa[PteFlushList.
Count] = BaseAddress;
01464 PteFlushList.
Count += 1;
01465 }
01466 *Previous =
ZeroKernelPte;
01467 BaseAddress = (PVOID)((PCHAR)BaseAddress +
PAGE_SIZE);
01468 Previous++;
01469 }
01470
01471
KeRaiseIrql (
DISPATCH_LEVEL, &OldIrql);
01472
MiFlushPteList (&PteFlushList,
TRUE,
ZeroKernelPte);
01473
KeLowerIrql (OldIrql);
01474
01475
#else
01476
01477
01478
01479
01480
01481
#ifdef _MI_SYSPTE_DEBUG_
01482
MiValidateSystemPtes (StartingPte, NumberOfPtes);
01483
#endif
01484
01485
MiFillMemoryPte (StartingPte,
01486 NumberOfPtes *
sizeof (
MMPTE),
01487
ZeroKernelPte.
u.Long);
01488
01489
#ifdef _MI_SYSPTE_DEBUG_
01490
01491
01492
01493
01494
01495
01496
KeFlushEntireTb (
TRUE,
TRUE);
01497
#endif
01498
01499
#endif
01500
01501
01502
01503
01504
01505 PteOffset = (ULONG_PTR)(StartingPte -
MmSystemPteBase);
01506
01507
#ifdef _MI_SYSPTE_DEBUG_
01508
if (PteOffset == 0) {
01509
KeBugCheckEx (SYSTEM_PTE_MISUSE,
01510 0x11,
01511 (ULONG_PTR)StartingPte,
01512 NumberOfPtes,
01513 SystemPtePoolType);
01514 }
01515
#endif
01516
01517
MiLockSystemSpace(OldIrql);
01518
01519
#ifdef _MI_SYSPTE_DEBUG_
01520
MiCheckPteRelease (StartingPte, NumberOfPtes);
01521
#endif
01522
01523
#ifndef _MI_GUARD_PTE_
01524
if ((SystemPtePoolType ==
SystemPteSpace) &&
01525 (NumberOfPtes <=
MM_PTE_TABLE_LIMIT)) {
01526
01527
Index =
MmSysPteTables [NumberOfPtes];
01528 NumberOfPtes =
MmSysPteIndex [
Index];
01529
01530
if (
MmTotalFreeSystemPtes[
SystemPteSpace] >=
MM_MIN_SYSPTE_FREE) {
01531
01532
01533
01534
01535
01536 i =
MmSysPteMinimumFree[
Index];
01537
if (
MmTotalFreeSystemPtes[
SystemPteSpace] >=
MM_MAX_SYSPTE_FREE) {
01538
01539
01540
01541
01542
01543 i = i * 4;
01544 }
01545 i += 15;
01546
if (
MmSysPteListBySizeCount[
Index] <= i) {
01547
01548
#if DBG
01549
if (MmDebug &
MM_DBG_SYS_PTES) {
01550
PMMPTE PointerPte1;
01551
01552 PointerPte1 = &
MmFreeSysPteListBySize[
Index];
01553
while (PointerPte1->
u.List.NextEntry !=
MM_EMPTY_PTE_LIST) {
01554
PMMPTE PointerFreedPte;
01555 ULONG j;
01556
01557 PointerPte1 =
MmSystemPteBase + PointerPte1->
u.List.NextEntry;
01558 PointerFreedPte = PointerPte1;
01559
for (j = 0; j <
MmSysPteIndex[
Index]; j++) {
01560
ASSERT (PointerFreedPte->
u.Hard.Valid == 0);
01561 PointerFreedPte++;
01562 }
01563 }
01564 }
01565
#endif //DBG
01566
MmSysPteListBySizeCount [
Index] += 1;
01567 PointerPte =
MmLastSysPteListBySize[
Index];
01568
ASSERT (PointerPte->
u.List.NextEntry ==
MM_EMPTY_PTE_LIST);
01569 PointerPte->
u.List.NextEntry = PteOffset;
01570
MmLastSysPteListBySize[
Index] = StartingPte;
01571 StartingPte->
u.List.NextEntry =
MM_EMPTY_PTE_LIST;
01572
01573
#if DBG
01574
if (MmDebug &
MM_DBG_SYS_PTES) {
01575
PMMPTE PointerPte1;
01576 PointerPte1 = &
MmFreeSysPteListBySize[
Index];
01577
while (PointerPte1->
u.List.NextEntry !=
MM_EMPTY_PTE_LIST) {
01578
PMMPTE PointerFreedPte;
01579 ULONG j;
01580
01581 PointerPte1 =
MmSystemPteBase + PointerPte1->
u.List.NextEntry;
01582 PointerFreedPte = PointerPte1;
01583
for (j = 0; j <
MmSysPteIndex[
Index]; j++) {
01584
ASSERT (PointerFreedPte->
u.Hard.Valid == 0);
01585 PointerFreedPte++;
01586 }
01587 }
01588 }
01589
#endif //DBG
01590
if (NumberOfPtes == 1) {
01591
if (
MmFlushPte1 ==
NULL) {
01592
MmFlushPte1 = StartingPte;
01593 }
01594 }
else {
01595 (StartingPte + 1)->
u.List.NextEntry =
MmFlushCounter;
01596 }
01597
01598
MiUnlockSystemSpace(OldIrql);
01599
return;
01600 }
01601 }
01602 }
01603
#endif
01604
01605
MmTotalFreeSystemPtes[SystemPtePoolType] += NumberOfPtes;
01606
01607 PteOffset = (ULONG_PTR)(StartingPte -
MmSystemPteBase);
01608 PointerPte = &
MmFirstFreeSystemPte[SystemPtePoolType];
01609
01610
while (
TRUE) {
01611 NextPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
01612
if (PteOffset < PointerPte->
u.List.NextEntry) {
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
ASSERT (((StartingPte + NumberOfPtes) <= NextPte) ||
01627 (PointerPte->
u.List.NextEntry ==
MM_EMPTY_PTE_LIST));
01628
01629 PointerFollowingPte = PointerPte + 1;
01630
if (PointerPte->u.List.OneEntry) {
01631
Size = 1;
01632 }
else {
01633
Size = (ULONG_PTR) PointerFollowingPte->
u.List.NextEntry;
01634 }
01635
if ((PointerPte +
Size) == StartingPte) {
01636
01637
01638
01639
01640
01641 NumberOfPtes += (ULONG)
Size;
01642 PointerFollowingPte->
u.List.NextEntry = NumberOfPtes;
01643 PointerPte->u.List.OneEntry = 0;
01644
01645
01646
01647
01648
01649
01650
01651 StartingPte = PointerPte;
01652
01653 }
else {
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664 StartingPte->u.List.NextEntry = PointerPte->u.List.NextEntry;
01665
01666
01667
01668
01669
01670 PointerPte->u.List.NextEntry = PteOffset;
01671
01672
01673
01674
01675
01676
if (NumberOfPtes == 1) {
01677 StartingPte->u.List.OneEntry = 1;
01678
01679 }
else {
01680 StartingPte->u.List.OneEntry = 0;
01681 PointerFollowingPte = StartingPte + 1;
01682 PointerFollowingPte->
u.List.NextEntry = NumberOfPtes;
01683 }
01684 }
01685
01686
01687
01688
01689
01690
01691
if ((StartingPte + NumberOfPtes) == NextPte) {
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702 StartingPte->u.List.NextEntry = NextPte->u.List.NextEntry;
01703 StartingPte->u.List.OneEntry = 0;
01704 PointerFollowingPte = StartingPte + 1;
01705
01706
if (NextPte->u.List.OneEntry) {
01707
Size = 1;
01708
01709 }
else {
01710 NextPte++;
01711
Size = (ULONG_PTR) NextPte->u.List.NextEntry;
01712 }
01713 PointerFollowingPte->
u.List.NextEntry = NumberOfPtes +
Size;
01714 }
01715
#if 0
01716
if (MmDebug &
MM_DBG_SYS_PTES) {
01717
MiDumpSystemPtes(SystemPtePoolType);
01718 }
01719
#endif //0
01720
01721
#if DBG
01722
if (MmDebug &
MM_DBG_SYS_PTES) {
01723
ASSERT (
MmTotalFreeSystemPtes[SystemPtePoolType] ==
01724
MiCountFreeSystemPtes (SystemPtePoolType));
01725 }
01726
#endif //DBG
01727
MiUnlockSystemSpace(OldIrql);
01728
return;
01729 }
01730
01731
01732
01733
01734
01735 PointerPte = NextPte;
01736 }
01737 }
01738
01739
VOID
01740 MiInitializeSystemPtes (
01741 IN
PMMPTE StartingPte,
01742 IN ULONG NumberOfPtes,
01743 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
01744 )
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 {
01772 LONG i;
01773 LONG j;
01774
#ifdef _MI_SYSPTE_DEBUG_
01775
PMMPTE_TRACKER Tracker;
01776
#endif
01777
01778
01779
01780
01781
01782
01783
MmSystemPteBase =
MI_PTE_BASE_FOR_LOWEST_KERNEL_ADDRESS;
01784
01785
MmSystemPtesStart[SystemPtePoolType] = StartingPte;
01786
MmSystemPtesEnd[SystemPtePoolType] = StartingPte + NumberOfPtes - 1;
01787
01788
01789
01790
01791
01792
01793
if (NumberOfPtes == 0) {
01794
MmFirstFreeSystemPte[SystemPtePoolType] =
ZeroKernelPte;
01795
MmFirstFreeSystemPte[SystemPtePoolType].
u.List.NextEntry =
01796
MM_EMPTY_LIST;
01797
return;
01798 }
01799
01800
01801
01802
01803
01804
MiFillMemoryPte (StartingPte,
01805 NumberOfPtes *
sizeof (
MMPTE),
01806
ZeroKernelPte.
u.Long);
01807
01808
01809
01810
01811
01812
01813
01814 StartingPte->u.List.NextEntry =
MM_EMPTY_LIST;
01815
01816
MmFirstFreeSystemPte[SystemPtePoolType] =
ZeroKernelPte;
01817
MmFirstFreeSystemPte[SystemPtePoolType].
u.List.NextEntry =
01818 StartingPte -
MmSystemPteBase;
01819
01820
01821
01822
01823
01824
01825
if (NumberOfPtes == 1) {
01826 StartingPte->
u.List.OneEntry =
TRUE;
01827
01828 }
else {
01829 StartingPte += 1;
01830
MI_WRITE_INVALID_PTE (StartingPte,
ZeroKernelPte);
01831 StartingPte->u.List.NextEntry = NumberOfPtes;
01832 }
01833
01834
01835
01836
01837
01838
MmTotalFreeSystemPtes[SystemPtePoolType] = NumberOfPtes;
01839
01840
ASSERT (
MmTotalFreeSystemPtes[SystemPtePoolType] ==
01841
MiCountFreeSystemPtes (SystemPtePoolType));
01842
01843
if (SystemPtePoolType ==
SystemPteSpace) {
01844
01845 ULONG Lists[
MM_SYS_PTE_TABLES_MAX] = {
MM_PTE_LIST_1,
MM_PTE_LIST_2,
MM_PTE_LIST_4,
MM_PTE_LIST_8,
MM_PTE_LIST_16};
01846
PMMPTE PointerPte;
01847 ULONG total;
01848
01849
#ifdef _MI_SYSPTE_DEBUG_
01850
Tracker = (PMMPTE_TRACKER)
MiAllocatePoolPages (
01851
NonPagedPool,
01852 NumberOfPtes *
sizeof (MMPTE_TRACKER),
01853 0);
01854
01855
if (Tracker) {
01856 RtlZeroMemory (Tracker, NumberOfPtes *
sizeof (MMPTE_TRACKER));
01857 }
01858
#endif
01859
01860
for (j = 0; j <
MM_SYS_PTE_TABLES_MAX ; j++) {
01861
MmFreeSysPteListBySize [j].
u.List.NextEntry =
MM_EMPTY_PTE_LIST;
01862
MmLastSysPteListBySize [j] = &
MmFreeSysPteListBySize [j];
01863 }
01864
MmFlushCounter += 1;
01865
01866
#ifndef _MI_GUARD_PTE_
01867
01868
01869
01870
01871
01872 total =
MM_PTE_LIST_1 *
MmSysPteIndex[0] +
01873
MM_PTE_LIST_2 *
MmSysPteIndex[1] +
01874
MM_PTE_LIST_4 *
MmSysPteIndex[2] +
01875
MM_PTE_LIST_8 *
MmSysPteIndex[3] +
01876
MM_PTE_LIST_16 *
MmSysPteIndex[4];
01877
01878 PointerPte =
MiReserveSystemPtes (total,
01879
SystemPteSpace,
01880 64*1024,
01881 0,
01882
TRUE);
01883
01884
for (i = (
MM_SYS_PTE_TABLES_MAX - 1); i >= 0; i--) {
01885
do {
01886 Lists[i] -= 1;
01887
MiReleaseSystemPtes (PointerPte,
01888
MmSysPteIndex[i],
01889
SystemPteSpace);
01890 PointerPte +=
MmSysPteIndex[i];
01891 }
while (Lists[i] != 0 );
01892 }
01893
#endif
01894
01895
MmFlushCounter += 1;
01896
MmFlushPte1 =
NULL;
01897
01898
#ifdef _MI_SYSPTE_DEBUG_
01899
MiPteTracker = Tracker;
01900
#endif
01901
}
01902
01903
return;
01904 }
01905
01906
VOID
01907 MiAddSystemPtes(
01908 IN
PMMPTE StartingPte,
01909 IN ULONG NumberOfPtes,
01910 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
01911 )
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938 {
01939
PMMPTE EndingPte;
01940
01941 EndingPte = StartingPte + NumberOfPtes - 1;
01942
01943
#ifdef _MI_SYSPTE_DEBUG_
01944
MiRebuildPteTracker (StartingPte, NumberOfPtes);
01945
#endif
01946
01947
if (StartingPte <
MmSystemPtesStart[SystemPtePoolType]) {
01948
MmSystemPtesStart[SystemPtePoolType] = StartingPte;
01949 }
01950
01951
if (EndingPte >
MmSystemPtesEnd[SystemPtePoolType]) {
01952
MmSystemPtesEnd[SystemPtePoolType] = EndingPte;
01953 }
01954
01955
#ifdef _MI_SYSPTE_DEBUG_
01956
01957
if (SystemPtePoolType ==
SystemPteSpace && MiPteTracker !=
NULL) {
01958
01959 ULONG i;
01960 ULONG_PTR
Index;
01961 PMMPTE_TRACKER Tracker;
01962
01963
Index = StartingPte -
MmSystemPtesStart[
SystemPteSpace];
01964 Tracker = &MiPteTracker[
Index];
01965
01966
ASSERT (NumberOfPtes < 0x10000);
01967 Tracker->NumberOfPtes = (
USHORT)NumberOfPtes;
01968
01969
for (i = 0; i < NumberOfPtes; i += 1) {
01970 Tracker->InUse =
TRUE;
01971 Tracker += 1;
01972 }
01973 }
01974
01975
MiFillMemoryPte (StartingPte, NumberOfPtes *
sizeof (
MMPTE),
MM_KERNEL_NOACCESS_PTE);
01976
#endif
01977
01978
#ifdef _MI_GUARD_PTE_
01979
MiReleaseSystemPtes (StartingPte, NumberOfPtes - 1, SystemPtePoolType);
01980
#else
01981
MiReleaseSystemPtes (StartingPte, NumberOfPtes, SystemPtePoolType);
01982
#endif
01983
}
01984
01985
01986 ULONG
01987 MiGetSystemPteListCount (
01988 IN ULONG ListSize
01989 )
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013 {
02014
#ifdef _MI_GUARD_PTE_
02015
UNREFERENCED_PARAMETER (ListSize);
02016
02017
return 8;
02018
#else
02019
ULONG
Index;
02020
02021
ASSERT (ListSize <=
MM_PTE_TABLE_LIMIT);
02022
02023
Index =
MmSysPteTables [ListSize];
02024
return MmSysPteListBySizeCount[
Index];
02025
#endif
02026
}
02027
02028
02029 LOGICAL
02030 MiGetSystemPteAvailability (
02031 IN ULONG NumberOfPtes,
02032 IN MM_PAGE_PRIORITY Priority
02033 )
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060 {
02061 ULONG
Index;
02062 ULONG FreePtes;
02063 ULONG FreeBinnedPtes;
02064
02065
if (Priority ==
HighPagePriority) {
02066
return TRUE;
02067 }
02068
02069
#ifdef _MI_GUARD_PTE_
02070
NumberOfPtes += 1;
02071
#endif
02072
02073 FreePtes =
MmTotalFreeSystemPtes[
SystemPteSpace];
02074
02075
if (NumberOfPtes <=
MM_PTE_TABLE_LIMIT) {
02076
Index =
MmSysPteTables [NumberOfPtes];
02077 FreeBinnedPtes =
MmSysPteListBySizeCount[
Index];
02078
02079
if (FreeBinnedPtes >
MmSysPteMinimumFree[
Index]) {
02080
return TRUE;
02081 }
02082
if (FreeBinnedPtes != 0) {
02083
if (Priority ==
NormalPagePriority) {
02084
if (FreeBinnedPtes > 1 || FreePtes > 512) {
02085
return TRUE;
02086 }
02087
return FALSE;
02088 }
02089
if (FreePtes > 2048) {
02090
return TRUE;
02091 }
02092
return FALSE;
02093 }
02094 }
02095
02096
if (Priority ==
NormalPagePriority) {
02097
if ((LONG)NumberOfPtes < (LONG)FreePtes - 512) {
02098
return TRUE;
02099 }
02100
return FALSE;
02101 }
02102
02103
if ((LONG)NumberOfPtes < (LONG)FreePtes - 2048) {
02104
return TRUE;
02105 }
02106
return FALSE;
02107 }
02108
02109
#if DBG
02110
02111
VOID
02112
MiDumpSystemPtes (
02113 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
02114 )
02115
02116
02117 {
02118
PMMPTE PointerPte;
02119
PMMPTE PointerNextPte;
02120 ULONG_PTR ClusterSize;
02121
PMMPTE EndOfCluster;
02122
02123 PointerPte = &
MmFirstFreeSystemPte[SystemPtePoolType];
02124
if (PointerPte->
u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
02125
return;
02126 }
02127
02128 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
02129
02130
for (;;) {
02131
if (PointerPte->
u.List.OneEntry) {
02132 ClusterSize = 1;
02133 }
else {
02134 PointerNextPte = PointerPte + 1;
02135 ClusterSize = (ULONG_PTR) PointerNextPte->
u.List.NextEntry;
02136 }
02137
02138 EndOfCluster = PointerPte + (ClusterSize - 1);
02139
02140
DbgPrint(
"System Pte at %p for %p entries (%p)\n",
02141 PointerPte, ClusterSize, EndOfCluster);
02142
02143
if (PointerPte->
u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
02144
break;
02145 }
02146
02147 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
02148 }
02149
return;
02150 }
02151
02152 ULONG
02153
MiCountFreeSystemPtes (
02154 IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
02155 )
02156
02157 {
02158
PMMPTE PointerPte;
02159
PMMPTE PointerNextPte;
02160 ULONG_PTR ClusterSize;
02161 ULONG_PTR FreeCount;
02162
02163 PointerPte = &
MmFirstFreeSystemPte[SystemPtePoolType];
02164
if (PointerPte->
u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
02165
return 0;
02166 }
02167
02168 FreeCount = 0;
02169
02170 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
02171
02172
for (;;) {
02173
if (PointerPte->
u.List.OneEntry) {
02174 ClusterSize = 1;
02175
02176 }
else {
02177 PointerNextPte = PointerPte + 1;
02178 ClusterSize = (ULONG_PTR) PointerNextPte->
u.List.NextEntry;
02179 }
02180
02181 FreeCount += ClusterSize;
02182
if (PointerPte->
u.List.NextEntry ==
MM_EMPTY_PTE_LIST) {
02183
break;
02184 }
02185
02186 PointerPte =
MmSystemPteBase + PointerPte->
u.List.NextEntry;
02187 }
02188
02189
return (ULONG)FreeCount;
02190 }
02191
02192
#endif //DBG
02193