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 "ki.h"
00025
#include "mm.h"
00026
#include "..\..\mm\mi.h"
00027
00028 extern KSPIN_LOCK
KiTbBroadcastLock;
00029 extern KSPIN_LOCK
KiMasterRidLock;
00030
00031 #define _x256mb (1024*1024*256)
00032
00033
00034
00035 #define KiFlushSingleTbGlobal(Invalid, Va) __ptcga((__int64)Va, PAGE_SHIFT << 2)
00036
00037 #define KiFlushSingleTbLocal(Invalid, va) __ptcl((__int64)va, PAGE_SHIFT << 2)
00038
00039 #define KiTbSynchronizeGlobal() { __mf(); __isrlz(); }
00040
00041 #define KiTbSynchronizeLocal() { __isrlz(); }
00042
00043 #define KiFlush2gbTbGlobal(Invalid) \
00044
{ \
00045
__ptcga((__int64)0, 28 << 2); \
00046
__ptcg((__int64)_x256mb, 28 << 2); \
00047
__ptcg((__int64)_x256mb*2,28 << 2); \
00048
__ptcg((__int64)_x256mb*3, 28 << 2); \
00049
__ptcg((__int64)_x256mb*4, 28 << 2); \
00050
__ptcg((__int64)_x256mb*5, 28 << 2); \
00051
__ptcg((__int64)_x256mb*6, 28 << 2); \
00052
__ptcg((__int64)_x256mb*7, 28 << 2); \
00053
}
00054
00055 #define KiFlush2gbTbLocal(Invalid) \
00056
{ \
00057
__ptcl((__int64)0, 28 << 2); \
00058
__ptcl((__int64)_x256mb, 28 << 2); \
00059
__ptcl((__int64)_x256mb*2,28 << 2); \
00060
__ptcl((__int64)_x256mb*3, 28 << 2); \
00061
__ptcl((__int64)_x256mb*4, 28 << 2); \
00062
__ptcl((__int64)_x256mb*5, 28 << 2); \
00063
__ptcl((__int64)_x256mb*6, 28 << 2); \
00064
__ptcl((__int64)_x256mb*7, 28 << 2); \
00065
}
00066
00067
00068
VOID
00069
KiSetProcessRid (
00070 ULONG NewProcessRid
00071 );
00072
00073
VOID
00074
KiSetRegionRegister (
00075 PVOID VirtualAddress,
00076 ULONGLONG Contents
00077 );
00078
00079
00080
00081
00082
00083
00084
VOID
00085
KiFlushEntireTbTarget (
00086 IN PULONG SignalDone,
00087 IN PVOID Parameter1,
00088 IN PVOID Parameter2,
00089 IN PVOID Parameter3
00090 );
00091
00092
VOID
00093
KiInvalidateForwardProgressTbBuffer(
00094 KAFFINITY TargetProcessors
00095 );
00096
00097
VOID
00098
KiFlushForwardProgressTbBuffer(
00099 KAFFINITY TargetProcessors
00100 );
00101
00102
VOID
00103
KiFlushForwardProgressTbBufferLocal(
00104 VOID
00105 );
00106
00107
00108
VOID
00109 KeFlushEntireTb (
00110 IN BOOLEAN Invalid,
00111 IN BOOLEAN AllProcessors
00112 )
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 {
00139
00140 KIRQL OldIrql;
00141 KAFFINITY TargetProcessors;
00142
PKTHREAD Thread;
00143 BOOLEAN NeedTbFlush =
FALSE;
00144
00145
ASSERT(KeGetCurrentIrql() <=
DISPATCH_LEVEL);
00146
00147 OldIrql = KeRaiseIrqlToSynchLevel();
00148
00149
#if !defined(NT_UP)
00150
TargetProcessors =
KeActiveProcessors;
00151 TargetProcessors &= PCR->NotMember;
00152
if (TargetProcessors != 0) {
00153
KiIpiSendPacket(TargetProcessors,
00154
KiFlushEntireTbTarget,
00155 (PVOID)NeedTbFlush,
00156
NULL,
00157
NULL);
00158 }
00159
00160
if (
PsGetCurrentProcess()->Wow64Process != 0) {
00161
KiInvalidateForwardProgressTbBuffer(TargetProcessors);
00162 }
00163
#endif
00164
00165
KeFlushCurrentTb();
00166
00167
00168
00169
00170
00171
#if !defined(NT_UP)
00172
00173
if (TargetProcessors != 0) {
00174
KiIpiStallOnPacketTargets(TargetProcessors);
00175 }
00176
00177
#endif
00178
00179
00180
00181
00182
00183
#if defined(NT_UP)
00184
00185
KeLowerIrql(OldIrql);
00186
00187
#else
00188
00189
if (TargetProcessors != 0) {
00190
KiIpiStallOnPacketTargets(TargetProcessors);
00191 }
00192
00193
KeLowerIrql(OldIrql);
00194
00195
#endif
00196
00197
return;
00198 }
00199
00200
00201
00202
VOID
00203 KiFlushEntireTbTarget (
00204 IN PULONG SignalDone,
00205 IN PVOID Parameter1,
00206 IN PVOID Parameter2,
00207 IN PVOID Parameter3
00208 )
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 {
00230
00231
#if !defined(NT_UP)
00232
00233
00234
00235
00236
00237
KiIpiSignalPacketDone(SignalDone);
00238
00239
KeFlushCurrentTb();
00240
00241
#endif
00242
00243
return;
00244 }
00245
00246
VOID
00247 KeFlushMultipleTb (
00248 IN ULONG Number,
00249 IN PVOID *Virtual,
00250 IN BOOLEAN Invalid,
00251 IN BOOLEAN AllProcessors,
00252 IN PHARDWARE_PTE *PtePointer OPTIONAL,
00253 IN HARDWARE_PTE PteValue
00254 )
00255
00256
00257
00258
00259
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
00291
00292
00293
00294
00295 {
00296
00297 ULONG
Index;
00298 PKPRCB Prcb;
00299 KAFFINITY TargetProcessors;
00300
PWOW64_PROCESS Wow64Process;
00301 KIRQL OldIrql;
00302 BOOLEAN Flush2gb =
FALSE;
00303
00304
#if 0
00305
ASSERT(KeGetCurrentIrql() ==
DISPATCH_LEVEL);
00306
#endif
00307
00308 OldIrql = KeRaiseIrqlToSynchLevel();
00309
00310 Wow64Process =
PsGetCurrentProcess()->Wow64Process;
00311
00312
#ifdef MI_ALTFLG_FLUSH2G
00313
if ((Wow64Process !=
NULL) &&
00314 ((Wow64Process->AltFlags &
MI_ALTFLG_FLUSH2G) != 0)) {
00315 Flush2gb =
TRUE;
00316 }
00317
#endif
00318
00319
00320
00321
00322
00323
00324
#if !defined(NT_UP)
00325
00326 TargetProcessors =
KeActiveProcessors;
00327 TargetProcessors &= PCR->NotMember;
00328
00329
if (TargetProcessors != 0) {
00330
00331
00332
00333
00334
00335
00336 KiAcquireSpinLock(&
KiTbBroadcastLock);
00337
00338
for (
Index = 0;
Index < Number;
Index += 1) {
00339
if (ARGUMENT_PRESENT(PtePointer)) {
00340 *PtePointer[
Index] = PteValue;
00341 }
00342
00343
00344
00345
00346
00347
00348
KiFlushSingleTbGlobal(Invalid,
Virtual[
Index]);
00349 }
00350
00351
if (Wow64Process !=
NULL) {
00352
KiFlushForwardProgressTbBuffer(TargetProcessors);
00353 }
00354
00355
if (Flush2gb ==
TRUE) {
00356
KiFlush2gbTbGlobal(Invalid);
00357 }
00358
00359
00360
00361
00362
00363
KiTbSynchronizeGlobal();
00364
00365 KiReleaseSpinLock(&
KiTbBroadcastLock);
00366
00367 }
00368
else {
00369
00370
for (
Index = 0;
Index < Number;
Index += 1) {
00371
if (ARGUMENT_PRESENT(PtePointer)) {
00372 *PtePointer[
Index] = PteValue;
00373 }
00374
00375
00376
00377
00378
00379
00380
KiFlushSingleTbLocal(Invalid,
Virtual[
Index]);
00381 }
00382
00383
if (Wow64Process !=
NULL) {
00384
KiFlushForwardProgressTbBufferLocal();
00385 }
00386
00387
if (Flush2gb ==
TRUE) {
00388
KiFlush2gbTbLocal(Invalid);
00389 }
00390
00391
KiTbSynchronizeLocal();
00392 }
00393
00394
#else
00395
for (
Index = 0;
Index < Number;
Index += 1) {
00396
if (ARGUMENT_PRESENT(PtePointer)) {
00397 *PtePointer[
Index] = PteValue;
00398 }
00399
00400
00401
00402
00403
00404
00405
KiFlushSingleTbLocal(Invalid,
Virtual[
Index]);
00406 }
00407
00408
if (Wow64Process !=
NULL) {
00409
KiFlushForwardProgressTbBufferLocal();
00410 }
00411
00412
if (Flush2gb ==
TRUE) {
00413
KiFlush2gbTbLocal(Invalid);
00414 }
00415
00416
KiTbSynchronizeLocal();
00417
00418
#endif
00419
00420
KeLowerIrql(OldIrql);
00421
00422
return;
00423 }
00424
00425
00426 HARDWARE_PTE
00427 KeFlushSingleTb (
00428 IN PVOID Virtual,
00429 IN BOOLEAN Invalid,
00430 IN BOOLEAN AllProcessors,
00431 IN PHARDWARE_PTE PtePointer,
00432 IN HARDWARE_PTE PteValue
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
00465
00466
00467
00468
00469
00470
00471 {
00472
00473 HARDWARE_PTE OldPte;
00474 PKPRCB Prcb;
00475 KAFFINITY TargetProcessors;
00476
PWOW64_PROCESS Wow64Process;
00477 KIRQL OldIrql;
00478 BOOLEAN Flush2gb =
FALSE;
00479
00480
#if 0
00481
ASSERT(KeGetCurrentIrql() ==
DISPATCH_LEVEL);
00482
#endif
00483
00484
00485
00486
00487
00488 OldIrql = KeRaiseIrqlToSynchLevel();
00489
00490
00491
00492
00493
00494 Wow64Process =
PsGetCurrentProcess()->Wow64Process;
00495
00496
#ifdef MI_ALTFLG_FLUSH2G
00497
if ((Wow64Process !=
NULL) &&
00498 ((Wow64Process->AltFlags &
MI_ALTFLG_FLUSH2G) != 0)) {
00499 Flush2gb =
TRUE;
00500 }
00501
#endif
00502
00503
00504
00505
00506
00507
00508 OldPte = *PtePointer;
00509 *PtePointer = PteValue;
00510
00511
#if !defined(NT_UP)
00512
00513 TargetProcessors =
KeActiveProcessors;
00514 TargetProcessors &= PCR->NotMember;
00515
00516
if (TargetProcessors != 0) {
00517
00518
00519
00520
00521
00522
00523 KiAcquireSpinLock(&
KiTbBroadcastLock);
00524
00525
KiFlushSingleTbGlobal(Invalid,
Virtual);
00526
00527
if (Wow64Process !=
NULL) {
00528
KiFlushForwardProgressTbBuffer(TargetProcessors);
00529 }
00530
00531
if (Flush2gb) {
00532
KiFlush2gbTbGlobal(Invalid);
00533 }
00534
00535
KiTbSynchronizeGlobal();
00536
00537 KiReleaseSpinLock(&
KiTbBroadcastLock);
00538
00539 }
00540
else {
00541
00542
00543
00544
00545
00546
00547
KiFlushSingleTbLocal(Invalid,
Virtual);
00548
00549
if (Wow64Process !=
NULL) {
00550
KiFlushForwardProgressTbBufferLocal();
00551 }
00552
00553
if (Flush2gb ==
TRUE) {
00554
KiFlush2gbTbLocal(Invalid);
00555 }
00556
00557
KiTbSynchronizeLocal();
00558
00559 }
00560
00561
#else
00562
00563
00564
00565
00566
00567
KiFlushSingleTbLocal(Invalid,
Virtual);
00568
00569
if (Wow64Process !=
NULL) {
00570
KiFlushForwardProgressTbBufferLocal();
00571 }
00572
00573
if (Flush2gb ==
TRUE) {
00574
KiFlush2gbTbLocal(Invalid);
00575 }
00576
00577
KiTbSynchronizeLocal();
00578
00579
#endif
00580
00581
00582
00583
00584
00585
KeLowerIrql(OldIrql);
00586
00587
00588
00589
00590
00591
return OldPte;
00592 }
00593
00594
VOID
00595 KiInvalidateForwardProgressTbBuffer(
00596 KAFFINITY TargetProcessors
00597 )
00598 {
00599 PKPRCB Prcb;
00600 ULONG BitNumber;
00601
PKPROCESS CurrentProcess;
00602
PKPROCESS TargetProcess;
00603 PKPCR Pcr;
00604 ULONG i;
00605
00606 CurrentProcess =
KeGetCurrentThread()->ApcState.Process;
00607
00608
00609
00610
00611
00612
for (i = 0; i < MAXIMUM_FWP_BUFFER_ENTRY; i += 1) {
00613
00614 PCR->ForwardProgressBuffer[(i*2)+1] = 0;
00615
00616 }
00617
00618
00619
00620
00621
00622
while (TargetProcessors != 0) {
00623
00624 BitNumber =
KeFindFirstSetRightMember(TargetProcessors);
00625
ClearMember(BitNumber, TargetProcessors);
00626 Prcb =
KiProcessorBlock[BitNumber];
00627
00628 Pcr = KSEG_ADDRESS(Prcb->PcrPage);
00629
00630 TargetProcess = Pcr->CurrentThread->ApcState.Process;
00631
00632
if (TargetProcess == CurrentProcess) {
00633
00634
for (i = 0; i < MAXIMUM_FWP_BUFFER_ENTRY; i += 1) {
00635
00636 Pcr->ForwardProgressBuffer[(i*2)+1] = 0;
00637
00638 }
00639 }
00640 }
00641 }
00642
00643
VOID
00644 KiFlushForwardProgressTbBuffer(
00645 KAFFINITY TargetProcessors
00646 )
00647 {
00648 PKPRCB Prcb;
00649 ULONG BitNumber;
00650
PKPROCESS CurrentProcess;
00651
PKPROCESS TargetProcess;
00652 PKPCR Pcr;
00653 ULONG i;
00654 PVOID Va;
00655
volatile ULONGLONG *PointerPte;
00656
00657 CurrentProcess =
KeGetCurrentThread()->ApcState.Process;
00658
00659
00660
00661
00662
00663
for (i = 0; i < MAXIMUM_FWP_BUFFER_ENTRY; i += 1) {
00664
00665 Va = (PVOID)PCR->ForwardProgressBuffer[i*2];
00666 PointerPte = &PCR->ForwardProgressBuffer[(i*2)+1];
00667
00668
if (*PointerPte != 0) {
00669 *PointerPte = 0;
00670
KiFlushSingleTbGlobal(Invalid, Va);
00671 }
00672
00673 }
00674
00675
00676
00677
00678
00679
while (TargetProcessors != 0) {
00680
00681 BitNumber =
KeFindFirstSetRightMember(TargetProcessors);
00682
ClearMember(BitNumber, TargetProcessors);
00683 Prcb =
KiProcessorBlock[BitNumber];
00684
00685 Pcr = KSEG_ADDRESS(Prcb->PcrPage);
00686
00687 TargetProcess = Pcr->CurrentThread->ApcState.Process;
00688
00689
if (TargetProcess == CurrentProcess) {
00690
00691
for (i = 0; i < MAXIMUM_FWP_BUFFER_ENTRY; i += 1) {
00692
00693 Va = (PVOID)Pcr->ForwardProgressBuffer[i*2];
00694 PointerPte = &Pcr->ForwardProgressBuffer[(i*2)+1];
00695
00696
if (*PointerPte != 0) {
00697 *PointerPte = 0;
00698
KiFlushSingleTbGlobal(Invalid, Va);
00699 }
00700 }
00701 }
00702 }
00703 }
00704
00705
VOID
00706 KiFlushForwardProgressTbBufferLocal(
00707 VOID
00708 )
00709 {
00710 ULONG i;
00711 PVOID Va;
00712
volatile ULONGLONG *PointerPte;
00713
00714
00715
00716
00717
00718
for (i = 0; i < MAXIMUM_FWP_BUFFER_ENTRY; i += 1) {
00719
00720 Va = (PVOID)PCR->ForwardProgressBuffer[i*2];
00721 PointerPte = &PCR->ForwardProgressBuffer[(i*2)+1];
00722
00723
if (*PointerPte != 0) {
00724 *PointerPte = 0;
00725
KiFlushSingleTbLocal(Invalid, Va);
00726 }
00727
00728 }
00729 }
00730
00731
00732 ULONG
00733 KiGetNewRid (
00734 IN PULONG ProcessNewRid,
00735 IN PULONGLONG ProcessNewSequence
00736 )
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 {
00767
00768 ULONG NewRid;
00769 KAFFINITY TargetProcessors;
00770
00771 KiMasterRid += 1;
00772
00773
if (KiMasterRid <= MAXIMUM_RID) {
00774
00775
00776
00777
00778
00779 *ProcessNewRid = KiMasterRid;
00780 *ProcessNewSequence = KiMasterSequence;
00781
00782
return (*ProcessNewRid);
00783 }
00784
00785
00786
00787
00788
00789
00790 KiMasterRid = START_PROCESS_RID;
00791
00792 KiMasterSequence += 1;
00793
00794
if (KiMasterSequence > MAXIMUM_SEQUENCE) {
00795
00796 KiMasterSequence = START_SEQUENCE;
00797
00798 }
00799
00800
00801
00802
00803
00804 *ProcessNewRid = KiMasterRid;
00805 *ProcessNewSequence = KiMasterSequence;
00806
00807
#if !defined(NT_UP)
00808
00809
00810
00811
00812
00813 TargetProcessors =
KeActiveProcessors;
00814 TargetProcessors &= PCR->NotMember;
00815
if (TargetProcessors != 0) {
00816
KiIpiSendPacket(TargetProcessors,
00817
KiFlushEntireTbTarget,
00818 (PVOID)
TRUE,
00819
NULL,
00820
NULL);
00821 }
00822
00823
#endif
00824
00825
KeFlushCurrentTb();
00826
00827
00828
#if !defined(NT_UP)
00829
00830
00831
00832
00833
00834
if (TargetProcessors != 0) {
00835
KiIpiStallOnPacketTargets(TargetProcessors);
00836 }
00837
00838
#endif
00839
00840
return *ProcessNewRid;
00841 }