MiMoveLargeFreePage
NTSTATUS __stdcall MiMoveLargeFreePage(
UINT64 PageFrameIndex,
UINT64 LargePageIndex,
_MI_PARTITION *FromPartition,
PVOID *ToPartition){
NTSTATUS v5;
__int64 v7;
UINT64 v8;
NTSTATUS result;
_MMPFN *v10;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v11;
__int64 v12;
unsigned __int64 v13;
unsigned __int64 v14;
unsigned __int64 v15;
_DWORD SpinCount[7];
v5 = 0;
v7 = MiLargePageSizes[(unsigned int)LargePageIndex];
v8 = PageFrameIndex & ~(v7 - 1);
result = MiTryUnlinkNodeLargePage((UINT64)FromPartition, v8);
if( result )
{
v10 = &MmGetPfnDb()[v8];
v11.Long = (unsigned __int64)v10->OriginalPte.u;
*(_OWORD *)&SpinCount[1] = 0i64;
*(_QWORD *)&SpinCount[5] = MiLockPageInline(v10);
SpinCount[3] = (v11.Long & 0x3E0) != 0i64;
v12 = ((unsigned __int64)v10->u4._bf_0 >> 39) & 0x3FF;
*(_QWORD *)&SpinCount[1] = v8;
SpinCount[4] = 0;
if( *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v12) == FromPartition )
{
_InterlockedAnd64(&v10->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v13 = (unsigned __int64)&v10[v7 - 1];
if( v13 >= (unsigned __int64)v10 )
{
v14 = v13 + 24;
v15 = (unsigned __int64)(*(_WORD *)ToPartition & 0x3FF) << 39;
do
{
SpinCount[0] = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v14, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)SpinCount);
while( *(__int64 *)v14 < 0 );
}
if( (*(_BYTE *)(v14 + 11) & 0x40) != 0 )
MiMoveBadPageCrossPartition(v13, (INT64)FromPartition, (UINT64 *)ToPartition);
*(_QWORD *)(v14 + 16) = v15 | *(_QWORD *)(v14 + 16) & 0xFFFE007FFFFFFFFFui64;
if( (_MMPFN *)v13 != v10 )
_InterlockedAnd64((volatile signed __int64 *)v14, 0x7FFFFFFFFFFFFFFFui64);
v13 -= 48i64;
v14 -= 48i64;
}
while( v13 >= (unsigned __int64)v10 );
}
v5 = 1;
}
MiInsertLargePageInNodeList((__int64)&SpinCount[1]);
return v5;
}
return result;
}Referenced by:
MiTransferPartitionPageRun