MiSwapNumaStandbyPage
NTSTATUS __fastcall MiSwapNumaStandbyPage(
UINT64 SuboptimalPage,
UINT64 PreferredNode,
UINT64 PreferredChannel,
UINT64 Flags){
__int64 v4;
_MMPFN *PfnDb;
unsigned int v6;
UINT64 v7;
unsigned int v8;
INT64 v9;
int v10;
__int64 v11;
__int64 v12;
unsigned __int8 *v13;
__int64 v14;
int v15;
__int64 v16;
__int64 v17;
unsigned __int64 v18;
_QWORD *v19;
UINT64 *v20;
unsigned __int64 v21;
unsigned __int8 CurrentIrql;
UINT64 v23;
_MMPFN *v24;
__int64 v25;
UINT64 v27;
unsigned __int64 v28;
volatile signed __int32 *v29;
unsigned int v30;
unsigned __int64 v31;
__int64 v32;
UINT64 v33;
UINT64 v34;
unsigned __int64 *v35;
UINT64 v36;
__int64 v37;
__int64 v38;
_MMPFN *v39;
_MMPFN *v40;
_MMPFN *v41;
__int64 v42;
_MMPFN *v43;
__int64 v44;
unsigned __int64 v45;
INT64 v46;
__int64 v47;
__int64 v48;
__int64 v49;
_QWORD *v50;
INT64 v51;
__int64 v52;
__int64 v53;
int v54;
unsigned int v55;
char v56;
char v57;
signed __int32 v58[8];
int v59;
unsigned int v60;
__int64 v61;
unsigned __int8 *v62;
int v63;
_QWORD *v64;
_KLOCK_QUEUE_HANDLE LockQueue;
unsigned __int64 v66;
UINT64 *SpinLock;
__int64 v68;
UINT64 SpinCount;
__int64 v70;
unsigned __int64 v71;
unsigned int v73;
v4 = (unsigned int)PreferredNode;
PfnDb = MmGetPfnDb();
memset(&LockQueue, 0, sizeof(LockQueue));
v6 = PreferredChannel;
v7 = SuboptimalPage;
v8 = MmNumberOfChannels;
v9 = (INT64)&PfnDb[SuboptimalPage];
v10 = 0;
v73 = 0;
v11 = (*(_QWORD *)(v9 + 40) >> 39) & 0x3FFi64;
v59 = 0;
v60 = MmNumberOfChannels;
v12 = *(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * v11);
v13 = 0i64;
v68 = v12;
v62 = 0i64;
v14 = *(_QWORD *)(v12 + 16) + 4544 * v4;
v70 = v14;
v15 = *(_DWORD *)(v14 + 4280) & 1;
v63 = v15;
if( (unsigned int)MmNumberOfChannels > 1 )
{
v13 = (unsigned __int8 *)(v14 + 4313);
v62 = (unsigned __int8 *)(v14 + 4313);
if( v15 )
{
if( (Flags & 0x20) != 0 )
{
v8 = 1;
v73 = v6;
v13 = 0i64;
v60 = 1;
v62 = 0i64;
goto LABEL_10;
}
if( (Flags & 8) != 0 )
{
v13 = (unsigned __int8 *)(v14 + 4317);
v62 = (unsigned __int8 *)(v14 + 4317);
}
}
else
{
LODWORD(v16) = MiSearchNumaNodeTable((PVOID)((v9 - (__int64)PfnDb) / 48));
if( *(_DWORD *)(v16 + 8) == (_DWORD)v4 )
return v7;
v13 = v62;
v10 = v6;
v8 = v60;
v15 = v63;
v12 = v68;
v59 = v6;
}
}
v6 = 0;
LABEL_10:
v71 = (unsigned __int64)&v13[v8];
while( 1 )
{
if( v13 )
{
if( v15 )
{
v6 = *v13;
v73 = v6;
LODWORD(v17) = MiSearchNumaNodeTable((PVOID)((v9 - (__int64)MmGetPfnDb()) / 48));
if( *(_DWORD *)(v17 + 8) == (_DWORD)v4 && v6 == MiGetPfnChannel(v9) )
return v7;
v12 = v68;
}
else
{
v73 = v10;
v6 = v10;
v10 = v10 + 1 < v8 ? v10 + 1 : 0;
v59 = v10;
}
}
v66 = v12 + 2752;
v18 = v12 + 2432;
v61 = v12 + 2432;
if( v12 + 2432 < (unsigned __int64)(v12 + 2752) )
break;
LABEL_33:
v13 = v62 + 1;
v62 = v13;
if( (unsigned __int64)v13 >= v71 )
return v7;
v8 = v60;
v15 = v63;
}
v19 = (_QWORD *)(192i64 * v6 + 3264 + v14);
v20 = (UINT64 *)(v12 + 2464);
v64 = v19;
v21 = v12 + 2752;
SpinLock = (UINT64 *)(v12 + 2464);
while( *v19 == 0xFFFFFFFFFi64 )
{
LABEL_31:
v18 += 40i64;
v20 += 5;
v19 += 3;
v61 = v18;
SpinLock = v20;
v64 = v19;
if( v18 >= v21 )
{
v10 = v59;
v14 = v70;
v6 = v73;
v12 = v68;
goto LABEL_33;
}
}
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = v20;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, v20);
v23 = *v19;
if( v23 == 0xFFFFFFFFFi64 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
__writecr8(CurrentIrql);
v19 = v64;
v18 = v61;
LABEL_30:
v21 = v66;
goto LABEL_31;
}
v24 = &MmGetPfnDb()[v23];
if( !_interlockedbittestandset64((volatile signed __int32 *)&v24->u2, 0x3Fui64) )
goto LABEL_35;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v24->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v24->u2._bf_0 < 0 );
}
if( (*(_BYTE *)(&v24->u3 + 1) & 7) != 2 )
{
LABEL_29:
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(CurrentIrql);
v18 = v61 - 40;
v20 = SpinLock - 5;
v19 = v64 - 3;
goto LABEL_30;
}
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = SpinLock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, SpinLock);
if( v23 != *v64 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
goto LABEL_29;
}
LABEL_35:
if( _interlockedbittestandset64((volatile signed __int32 *)(v9 + 24), 0x3Fui64) )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
goto LABEL_39;
}
if( MiCanPageMove(v24) )
{
if( *(&stru_140C4DB30 + 567) != 1 )
goto LABEL_51;
v27 = v23 & 0x1F;
LOBYTE(v28) = 1;
v29 = (volatile signed __int32 *)(*(&stru_140C4DB30 + 295) + 4 * (v23 >> 5));
if( v27 + 1 > 0x20 )
{
if( (v23 & 0x1F) != 0 )
{
_InterlockedOr(v29++, ((1 << (32 - (v23 & 0x1F))) - 1) << v27);
v28 = 1i64 - (32 - (unsigned int)(v23 & 0x1F));
if( v28 >= 0x20 )
{
v31 = v28 >> 5;
v28 += -32i64 * (v28 >> 5);
do
{
*v29++ = -1;
--v31;
}
while( v31 );
}
if( !v28 )
{
LABEL_51:
v32 = v25 & v24->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0;
v33 = v25 & v24->u2._bf_0;
v34 = v25 & v7;
if( (*((_BYTE *)&v24->u3 + 3) & 8) != 0 )
{
if( MiIsDecayPfn(v33) )
{
LODWORD(v37) = MiUpdateTransitionPteFrame(v35[2], v7);
*(_QWORD *)(v38 + 16) = v37;
}
else
{
*v35 = v34 | *v35 & 0xFFFFFFF000000000ui64;
}
if( MiIsDecayPfn(v36) )
{
v39->u4._bf_0 = v34 | v39->u4._bf_0 & 0xFFFFFFF000000000ui64;
LABEL_65:
MiUnlinkNumaStandbyPage(v24);
MiFinalizePageAttribute(
(_MMPFN *)v9,
(_MI_PFN_CACHE_ATTRIBUTE)(*((unsigned __int8 *)&v24->u3 + 2) >> 6),
1ui64);
MiCopyPfnEntryEx(v9, (INT64)v24);
MiInsertNumaStandbyPage(v43);
_InterlockedOr(v58, 0);
if( (((unsigned __int8)KiTbFlushTimeStamp ^ *(_BYTE *)(v9 + 31)) & 0xF) != 0 )
MiSetPfnTbFlushStamp((_MMPFN *)v9, (unsigned int)KiTbFlushTimeStamp, 1ui64);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
v44 = v24->u4._bf_0 & 0xFFFFFFFFFi64;
if( v44 == v23 )
{
v45 = v34 | *(_QWORD *)(v9 + 40) & 0xFFFFFFF000000000ui64;
v46 = SuboptimalPage;
*(_QWORD *)(v9 + 40) = v45;
LODWORD(v47) = KeMakeKernelDirectoryTableBase(SuboptimalPage << 12);
*(_QWORD *)((v49 | v48) - 1392) = v47;
v50 = (_QWORD *)(v49 | v24->PteLong);
}
else
{
v46 = SuboptimalPage;
v50 = (char *)MiMapPageInHyperSpaceWorker(v24->u4._bf_0 & 0xFFFFFFFFFi64, 0i64, 0x80000000ui64)
+ 8 * ((LODWORD(v24->PteLong) >> 3) & 0x1FF);
}
LODWORD(v51) = MI_READ_PTE_LOCK_FREE((INT64)v50);
LODWORD(v52) = MiUpdateTransitionPteFrame(v51, v46);
v53 = v52;
LOBYTE(v54) = MiPteInShadowRange((UINT64)v50);
if( v54 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v53 & 1) != 0 )
v53 |= 0x8000000000000000ui64;
*v50 = v53;
if( v44 != v23 )
MiUnmapPageInHyperSpaceWorker(v50, 0x11u, 0x80000000ui64);
MiCopyPage(SuboptimalPage, v23, 0i64, 6ui64);
_InterlockedOr(v58, 0);
v55 = KiTbFlushTimeStamp;
if( (((unsigned __int8)KiTbFlushTimeStamp ^ *(_BYTE *)(v9 + 31)) & 0xF) != 0 )
{
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = (unsigned __int64 *volatile)(v61 + 32);
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, (UINT64 *)(v61 + 32));
MiSetPfnTbFlushStamp((_MMPFN *)v9, v55, 1ui64);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
}
_InterlockedAnd64((volatile signed __int64 *)(v9 + 24), 0x7FFFFFFFFFFFFFFFui64);
v56 = *((_BYTE *)&v24->u3 + 2);
v24->u4._bf_0 &= ~0x8000000000000000ui64;
*((_BYTE *)&v24->u3 + 2) = v56 & 0xC7;
*((_BYTE *)&v24->u3 + 3) &= ~0x20u;
_InterlockedOr(v58, 0);
MiSetPfnTbFlushStamp(v24, (unsigned int)KiTbFlushTimeStamp, 1ui64);
v24->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
MiSetPfnBlink(v24, 0i64, 1ui64);
*((_BYTE *)&v24->u3 + 2) = *(_BYTE *)(&v24->u3 + 1) & 0xF8 | 5;
v24->OriginalPte = ZeroPte;
MiSetOriginalPtePfnFromFreeList(&v24->OriginalPte.u.Long);
v57 = *((_BYTE *)&v24->u3 + 3);
v24->u4._bf_0 &= 0x8FFFFFFFFFFFFFFFui64;
*((_BYTE *)&v24->u3 + 3) = v57 & 0xF7;
*((_BYTE *)&v24->u3 + 3) &= 0xF8u;
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(CurrentIrql);
return v23;
}
v40 = v39;
}
else
{
v41 = MmGetPfnDb();
if( v33 == v25 )
{
v42 = v61;
*(_QWORD *)(v61 + 16) = v7;
}
else
{
v41[v33].u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = v34 | v41[v33].u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFF000000000ui64;
v42 = v61;
}
if( v32 == v25 )
{
*(_QWORD *)(v42 + 24) = v7;
goto LABEL_65;
}
v40 = &v41[v32];
}
MiSetPfnBlink(v40, v7, 0i64);
goto LABEL_65;
}
}
v30 = (1 << v28) - 1;
}
else
{
v30 = 1 << v27;
}
_InterlockedOr(v29, v30);
goto LABEL_51;
}
_InterlockedAnd64((volatile signed __int64 *)(v9 + 24), 0x7FFFFFFFFFFFFFFFui64);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
MiReuseStandbyPage(v24);
v24->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
MiReleaseFreshPage((_MMPFN *)v9);
LODWORD(v7) = v23;
LABEL_39:
__writecr8(CurrentIrql);
return v7;
}Referenced by:
MiGetPage
MiPruneStandbyPages