00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "ki.h"
00024
#include "mm.h"
00025
#include "..\..\mm\mi.h"
00026
00027
VOID
00028
KiSetRegionRegister (
00029 PVOID VirtualAddress,
00030 ULONGLONG Contents
00031 );
00032
00033
00034 #define KiMakeValidRegionRegister(Rid, Ps) \
00035
(((ULONGLONG)Rid << RR_RID) | (Ps << RR_PS) | (1 << RR_VE))
00036
00037 ULONG
KiMaximumRid = MAXIMUM_RID;
00038
00039
00040
VOID
00041 KiSyncNewRegionIdTarget (
00042 IN PULONG SignalDone,
00043 IN PVOID Parameter1,
00044 IN PVOID Parameter2,
00045 IN PVOID Parameter3
00046 )
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 {
00068
#if !defined(NT_UP)
00069
00070
PKTHREAD Thread;
00071
PKPROCESS Process;
00072 PREGION_MAP_INFO ProcessRegion;
00073 PREGION_MAP_INFO MappedSession;
00074 ULONG NewRid;
00075
00076
00077
00078
00079
00080 Thread =
KeGetCurrentThread();
00081 Process = Thread->
ApcState.
Process;
00082 ProcessRegion = &Process->ProcessRegion;
00083 MappedSession = Process->SessionMapInfo;
00084
00085 KiAcquireSpinLock(&
KiMasterRidLock);
00086
00087
if (ProcessRegion->SequenceNumber != KiMasterSequence) {
00088
00089 KiMasterRid += 1;
00090
00091 ProcessRegion->RegionId = KiMasterRid;
00092 ProcessRegion->SequenceNumber = KiMasterSequence;
00093
00094
KiSetRegionRegister(MM_LOWEST_USER_ADDRESS,
00095
KiMakeValidRegionRegister(ProcessRegion->RegionId,
PAGE_SHIFT));
00096
00097 }
00098
00099
if (MappedSession->SequenceNumber != KiMasterSequence) {
00100
00101 KiMasterRid += 1;
00102
00103 MappedSession->RegionId = KiMasterRid;
00104 MappedSession->SequenceNumber = KiMasterSequence;
00105
00106
KiSetRegionRegister((PVOID)
MM_SESSION_SPACE_DEFAULT,
00107
KiMakeValidRegionRegister(MappedSession->RegionId,
PAGE_SHIFT));
00108 }
00109
00110
00111 KiReleaseSpinLock(&
KiMasterRidLock);
00112
00113
KiIpiSignalPacketDone(SignalDone);
00114
00115
KeFlushCurrentTb();
00116
00117
#endif
00118
return;
00119 }
00120
00121 BOOLEAN
00122 KiSyncNewRegionId(
00123 IN PREGION_MAP_INFO ProcessRegion,
00124 IN PREGION_MAP_INFO SessionRegion
00125 )
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 {
00157 BOOLEAN RidRecycled =
FALSE;
00158 KAFFINITY TargetProcessors;
00159 ULONG i;
00160
00161
00162
00163
00164
00165
for (i = 0; i < MAXIMUM_FWP_BUFFER_ENTRY; i += 1) {
00166
00167 PCR->ForwardProgressBuffer[(i*2)+1] = 0;
00168
00169 }
00170
00171 KiAcquireSpinLock(&
KiMasterRidLock);
00172
00173
if ((ProcessRegion->SequenceNumber == KiMasterSequence) &&
00174 (SessionRegion->SequenceNumber == KiMasterSequence)) {
00175
00176
goto not_recycled;
00177
00178 }
00179
00180
if (ProcessRegion->SequenceNumber != KiMasterSequence) {
00181
00182
if (KiMasterRid + 1 >
KiMaximumRid) {
00183
00184 RidRecycled =
TRUE;
00185
00186 }
else {
00187
00188 KiMasterRid += 1;
00189 ProcessRegion->RegionId = KiMasterRid;
00190 ProcessRegion->SequenceNumber = KiMasterSequence;
00191 }
00192
00193 }
00194
00195
if ((RidRecycled ==
FALSE) &&
00196 (SessionRegion->SequenceNumber != KiMasterSequence)) {
00197
00198
if (KiMasterRid + 1 >
KiMaximumRid) {
00199
00200 RidRecycled =
TRUE;
00201
00202 }
else {
00203
00204 KiMasterRid += 1;
00205 SessionRegion->RegionId = KiMasterRid;
00206 SessionRegion->SequenceNumber = KiMasterSequence;
00207 }
00208 }
00209
00210
if (RidRecycled ==
FALSE) {
00211
00212
goto not_recycled;
00213
00214 }
00215
00216
00217
00218
00219
00220 KiMasterRid = START_PROCESS_RID;
00221
00222
00223
00224
00225
00226
if (KiMasterSequence + 1 > MAXIMUM_SEQUENCE) {
00227
00228 KiMasterSequence = START_SEQUENCE;
00229
00230 }
else {
00231
00232 KiMasterSequence += 1;
00233 }
00234
00235
00236
00237
00238
00239 ProcessRegion->RegionId = KiMasterRid;
00240 ProcessRegion->SequenceNumber = KiMasterSequence;
00241
00242
KiSetRegionRegister(MM_LOWEST_USER_ADDRESS,
00243
KiMakeValidRegionRegister(ProcessRegion->RegionId,
PAGE_SHIFT));
00244
00245 KiMasterRid += 1;
00246
00247 SessionRegion->RegionId = KiMasterRid;
00248 SessionRegion->SequenceNumber = KiMasterSequence;
00249
00250
KiSetRegionRegister((PVOID)
MM_SESSION_SPACE_DEFAULT,
00251
KiMakeValidRegionRegister(SessionRegion->RegionId,
PAGE_SHIFT));
00252
00253
00254
00255
00256
00257 KiReleaseSpinLock(&
KiMasterRidLock);
00258
00259
#if !defined(NT_UP)
00260
00261
00262
00263
00264
00265 TargetProcessors =
KeActiveProcessors;
00266 TargetProcessors &= PCR->NotMember;
00267
00268
if (TargetProcessors != 0) {
00269
KiIpiSendPacket(TargetProcessors,
00270
KiSyncNewRegionIdTarget,
00271 (PVOID)
TRUE,
00272
NULL,
00273
NULL);
00274 }
00275
00276
#endif
00277
00278
KeFlushCurrentTb();
00279
00280
00281
#if !defined(NT_UP)
00282
00283
00284
00285
00286
00287
if (TargetProcessors != 0) {
00288
KiIpiStallOnPacketTargets(TargetProcessors);
00289 }
00290
00291
#endif
00292
00293
return TRUE;
00294
00295
00296 not_recycled:
00297
00298
KiSetRegionRegister(MM_LOWEST_USER_ADDRESS,
00299
KiMakeValidRegionRegister(ProcessRegion->RegionId,
PAGE_SHIFT));
00300
00301
KiSetRegionRegister((PVOID)
MM_SESSION_SPACE_DEFAULT,
00302
KiMakeValidRegionRegister(SessionRegion->RegionId,
PAGE_SHIFT));
00303
00304
00305
00306
00307
00308 KiReleaseSpinLock(&
KiMasterRidLock);
00309
00310
return FALSE;
00311
00312 }
00313
00314
VOID
00315 KeEnableSessionSharing(
00316 PREGION_MAP_INFO SessionMapInfo
00317 )
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 {
00338
PKPROCESS Process;
00339
PKTHREAD Thread;
00340 KIRQL OldIrql;
00341
00342 Thread =
KeGetCurrentThread();
00343 Process = Thread->
ApcState.
Process;
00344
00345
00346
00347
00348
00349
KiLockDispatcherDatabase(&OldIrql);
00350
00351 SessionMapInfo->RegionId = Process->SessionRegion.RegionId;
00352 SessionMapInfo->SequenceNumber = Process->SessionRegion.SequenceNumber;
00353
00354 Process->SessionMapInfo = SessionMapInfo;
00355
00356
00357
00358
00359
00360
KiUnlockDispatcherDatabase(OldIrql);
00361 }
00362
00363
VOID
00364 KeDisableSessionSharing(
00365 PREGION_MAP_INFO SessionMapInfo
00366 )
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 {
00388
PKPROCESS Process;
00389
PKTHREAD Thread;
00390 KIRQL OldIrql;
00391
00392 Thread =
KeGetCurrentThread();
00393 Process = Thread->
ApcState.
Process;
00394
00395
00396
00397
00398
00399
KiLockDispatcherDatabase(&OldIrql);
00400
00401 Process->SessionRegion.RegionId = SessionMapInfo->RegionId;
00402 Process->SessionRegion.SequenceNumber = SessionMapInfo->SequenceNumber;
00403 Process->SessionMapInfo = &Process->SessionRegion;
00404
00405
00406
00407
00408
00409
KiUnlockDispatcherDatabase(OldIrql);
00410 }
00411
00412
VOID
00413 KeAttachSessionSpace(
00414 PREGION_MAP_INFO SessionMapInfo
00415 )
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 {
00436 KIRQL OldIrql;
00437
PKTHREAD Thread;
00438
PKPROCESS Process;
00439
00440 Thread =
KeGetCurrentThread();
00441 Process = Thread->
ApcState.
Process;
00442
00443
00444
00445
00446
00447
KiLockDispatcherDatabase(&OldIrql);
00448
00449
ASSERT(SessionMapInfo !=
NULL);
00450
00451
00452
00453
00454
00455 Process->SessionMapInfo = SessionMapInfo;
00456
00457
KiSyncNewRegionId(&Process->ProcessRegion, SessionMapInfo);
00458
00459
00460
00461
00462
00463
KiUnlockDispatcherDatabase(OldIrql);
00464
00465 }
00466
00467
VOID
00468 KiSyncSessionTarget(
00469 IN PULONG SignalDone,
00470 IN
PKPROCESS Process,
00471 IN PVOID Parameter1,
00472 IN PVOID Parameter2
00473 )
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 {
00499
#if !defined(NT_UP)
00500
00501
PKTHREAD Thread;
00502 ULONG NewRid;
00503
00504
00505
00506
00507
00508 Thread =
KeGetCurrentThread();
00509
00510
00511
00512
00513
00514
00515
if (Process == Thread->
ApcState.
Process) {
00516
00517 KiAcquireSpinLock(&
KiMasterRidLock);
00518
00519
00520
00521
00522
00523
KiSetRegionRegister((PVOID)
MM_SESSION_SPACE_DEFAULT,
00524
KiMakeValidRegionRegister(Process->SessionMapInfo->RegionId,
PAGE_SHIFT));
00525
00526 KiReleaseSpinLock(&
KiMasterRidLock);
00527
00528
00529
00530
00531
00532
KeFlushCurrentTb();
00533 }
00534
00535
KiIpiSignalPacketDone(SignalDone);
00536
00537
#endif
00538
return;
00539 }
00540
00541
00542
VOID
00543 KeDetachSessionSpace(
00544 VOID
00545 )
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 {
00568 KIRQL OldIrql;
00569
PKTHREAD Thread;
00570
PKPROCESS Process;
00571
#if !defined(NT_UP)
00572
KAFFINITY TargetProcessors;
00573
#endif
00574
00575
00576
00577
00578
00579
KiLockDispatcherDatabase(&OldIrql);
00580
00581 Thread =
KeGetCurrentThread();
00582 Process = Thread->
ApcState.
Process;
00583
00584
00585
00586
00587
00588 KiAcquireSpinLock(&
KiMasterRidLock);
00589
00590 Process->SessionMapInfo = &Process->SessionRegion;
00591
00592
KiSetRegionRegister((PVOID)
MM_SESSION_SPACE_DEFAULT,
00593
KiMakeValidRegionRegister(Process->SessionMapInfo->RegionId,
PAGE_SHIFT));
00594
00595
00596
00597
00598
00599 KiReleaseSpinLock(&
KiMasterRidLock);
00600
00601
#if !defined(NT_UP)
00602
00603
00604
00605
00606
00607 TargetProcessors =
KeActiveProcessors;
00608 TargetProcessors &= PCR->NotMember;
00609
00610
if (TargetProcessors != 0) {
00611
KiIpiSendPacket(TargetProcessors,
00612
KiSyncSessionTarget,
00613 Process,
00614
NULL,
00615
NULL);
00616 }
00617
00618
#endif
00619
00620
00621
00622
00623
00624
KiUnlockDispatcherDatabase(OldIrql);
00625 }
00626
00627
VOID
00628 KeAddSessionSpace(
00629
PKPROCESS Process,
00630 PREGION_MAP_INFO SessionMapInfo
00631 )
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 {
00659 KIRQL OldIrql;
00660
00661
ASSERT (Process->SessionMapInfo ==
NULL);
00662
00663
00664
00665 Process->SessionMapInfo = SessionMapInfo;
00666
00667
00668
00669 }
00670