MiZeroPage
VOID __stdcall MiZeroPage(INT64 rcx0, INT64 a2){
INT64 v3;
INT64 v4;
void *v5;
__int64 v6;
__int64 v7;
UINT64 v8;
__int64 v9;
int v10;
int v11;
unsigned __int64 v12;
INT64 v13;
int v14;
__int64 v15;
_QWORD *v16;
INT64 v17;
char v18;
INT64 v19;
__int64 v20;
unsigned __int64 v21;
__int64 v22;
int v23;
char v24;
__int64 v25;
unsigned __int64 v26;
unsigned __int64 PteBase;
_MMPTE *PteLimit;
unsigned __int64 v29;
unsigned __int64 v30;
__int64 v31;
__int64 *v32;
__int64 v33;
unsigned __int64 v34;
__int64 *v35;
__int64 v36;
unsigned __int64 v37;
__int64 v38;
unsigned __int64 v39;
INT64 v40;
__int64 v41;
unsigned __int64 i;
__int64 v43;
UINT64 v44;
char v45;
RTL_BITMAP *v46;
unsigned __int64 *v47;
signed __int32 SizeOfBitMap;
bool v49;
signed __int32 v50;
char v51;
__int64 v52;
unsigned int v53;
unsigned int v54;
__int64 v55;
__int64 v56;
int v57;
__int64 v58;
int v59;
INT64 v60;
char v61;
unsigned int v62;
unsigned int LargePageIndex;
int LargePageIndex_4;
INT64 v65;
int v66;
unsigned int v67[3];
unsigned int v68;
unsigned __int8 CurrentIrql;
int v71;
BOOL v72;
int v73;
char SpinCount[12];
PVOID P;
INT64 v76;
INT64 CurrentThread;
INT64 v78;
__int64 v79;
struct _KLOCK_QUEUE_HANDLE LockHandle;
INT64 v81;
__int64 v82;
__int64 v83;
__int64 Base;
__int128 v85;
__int128 v86;
__int128 v87;
__int128 v88;
__int128 v89;
__int128 v90;
__int128 v91;
__int128 v92;
__int128 v93;
__int64 v94;
*(_QWORD *)&SpinCount[4] = a2;
P = (PVOID)rcx0;
v78 = rcx0;
memset(&LockHandle, 0, sizeof(LockHandle));
v67[2] = 0;
v3 = *(_QWORD *)(rcx0 + 72);
v76 = v3;
CurrentThread = v3;
v4 = rcx0;
v65 = rcx0;
v5 = *(void **)(rcx0 + 40);
v6 = *(unsigned int *)(v4 + 64);
LargePageIndex = v6;
*(_QWORD *)v67 = v6;
v79 = v6;
if( (unsigned int)v6 >= 3 )
{
v7 = 1i64;
}
else
{
v7 = MiLargePageSizes[v6];
if( *(_BYTE *)(v4 + 80) && !(_DWORD)v6 )
{
*(_QWORD *)&v67[1] = *(_QWORD *)(v4 + 224);
v5 = (void *)(*(_QWORD *)(*(_QWORD *)&v67[1] + 176i64) + ((unsigned __int64)*(unsigned __int16 *)(v4 + 216) << 21));
v4 = *(_QWORD *)&v67[1];
v65 = *(_QWORD *)&v67[1];
v7 = 512i64;
}
}
if( v4 == rcx0 )
++dword_140C2A0B8[v6];
v8 = v7 << 12;
if( (unsigned int)v6 <= 1 )
++dword_140C2A078[v6];
KeZeroPages(v5, v8);
v9 = *(_QWORD *)&SpinCount[4];
v62 = 1;
v10 = 1;
v73 = 1;
v11 = 0;
LargePageIndex_4 = 0;
v66 = 0;
v68 = 0;
CurrentThread = (INT64)KeGetCurrentThread();
if( (unsigned int)MiColdPageSizeSupported() && !*(_BYTE *)(v13 + 195) && !*(_BYTE *)(v4 + 70) && !*(_BYTE *)(v4 + 69) )
{
v66 = 1;
v68 = MiSetZeroPageThreadPriority(*(INT64 *)&SpinCount[4], v13, 1i64);
--*(_WORD *)(CurrentThread + 486);
ExAcquirePushLockSharedEx(v9 + 192, 0i64);
}
P = 0i64;
if( *(_QWORD *)&v67[1] )
{
v11 = 1;
v3 = *(_QWORD *)(*(_QWORD *)&v67[1] + 168i64);
v76 = v3;
KeAcquireInStackQueuedSpinLock(
(UINT64 *)(qword_140C50AD0 + 4544i64 * *(unsigned int *)(*(_QWORD *)&v67[1] + 184i64) + 4304),
&LockHandle);
}
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v71 = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v3 + 24), 0x3Fui64) )
{
do
{
++v71;
_mm_pause();
}
while( *(__int64 *)(v3 + 24) < 0 );
}
if( *(_QWORD *)&v67[1] )
{
v62 = 0;
v10 = 0;
if( *(_BYTE *)(v65 + 69) != 1 )
{
if( ++*(_DWORD *)(*(_QWORD *)&v67[1] + 192i64) != 512 )
{
v73 = 0;
goto LABEL_32;
}
v10 = 1;
}
v62 = v10;
v14 = *(_DWORD *)(*(_QWORD *)&v67[1] + 188i64);
if( v14 == 1 )
{
v15 = *(_QWORD *)(*(_QWORD *)&v67[1] + 72i64);
v16 = *(_QWORD **)(*(_QWORD *)&v67[1] + 80i64);
if( *(_QWORD *)(v15 + 8) != *(_QWORD *)&v67[1] + 72i64 || *v16 != *(_QWORD *)&v67[1] + 72i64 )
__fastfail(3u);
*v16 = v15;
*(_QWORD *)(v15 + 8) = v16;
v10 = 1;
P = *(PVOID *)&v67[1];
}
else
{
*(_DWORD *)(*(_QWORD *)&v67[1] + 188i64) = v14 - 1;
v62 = v10;
}
}
LABEL_32:
v17 = v65;
v18 = *(_BYTE *)(v65 + 69);
v61 = v18;
if( v10 != 1 )
{
LABEL_87:
v19 = rcx0;
goto LABEL_88;
}
if( v11 != 1 )
{
v20 = *(unsigned int *)(rcx0 + 64);
v21 = *(_QWORD *)(rcx0 + 32);
v81 = 0i64;
v85 = 0i64;
v86 = 0i64;
v87 = 0i64;
v88 = 0i64;
v89 = 0i64;
v90 = 0i64;
v91 = 0i64;
v92 = 0i64;
v93 = 0i64;
v94 = 0i64;
v22 = 0i64;
v12 = 0i64;
v82 = 20i64;
v23 = 0;
v24 = 0;
v25 = 0i64;
v83 = 0i64;
Base = 0i64;
if( (unsigned int)v20 <= 1 )
{
MiInsertLargeTbFlushEntry((INT64)&v81, (unsigned int)(2 - v20), v21);
v22 = 1i64;
v25 = v83;
v12 = HIDWORD(v82);
v24 = BYTE4(v81);
v23 = v81;
}
v26 = v21;
PteBase = (unsigned __int64)MmGetPteBase();
PteLimit = MmGetPteLimit();
if( v21 >= PteBase )
{
do
{
if( v26 > (unsigned __int64)PteLimit )
break;
v26 = (__int64)((v26 << 25) - (PteBase << 25)) >> 16;
}
while( v26 >= PteBase );
}
v72 = (!qword_140C4E938 || v26 < qword_140C4E938 || v26 >= qword_140C4E938 + (qword_140C4E948 << 30))
&& (unsigned int)v20 <= 1;
if( v22 )
goto LABEL_82;
v29 = PteBase << 25;
v30 = (__int64)((v21 << 25) - (PteBase << 25)) >> 16;
if( (_DWORD)v20 != 3 )
{
if( (_DWORD)v20 == 2 )
{
v22 = 16i64;
MiInsertTbFlushEntry((INT64)&v81, v30, 16i64, 0i64);
}
else
{
v40 = MiLargePageSizes[v20];
if( (unsigned int)v20 <= 1 )
{
v41 = (unsigned int)(2 - v20);
do
{
MiInsertTbFlushEntry((INT64)&v81, v30, v40, 0i64);
v30 = (__int64)((v30 << 25) - v29) >> 16;
v40 <<= 9;
--v41;
}
while( v41 );
}
v22 = 512i64;
}
goto LABEL_82;
}
v22 = 1i64;
v31 = 1i64;
if( v23 != 1 && (v24 & 8) == 0 && v30 >= (unsigned __int64)MmGetPteBase() && v30 <= (unsigned __int64)PteLimit )
{
v24 |= 8u;
BYTE4(v81) = v24;
}
if( (_DWORD)v12 )
{
if( (v24 & 4) == 0 )
{
v32 = &Base + (unsigned int)(v12 - 1);
v33 = *v32;
if( (*v32 & 0xC00) == 0 )
{
v34 = *v32 & 0x3FF;
if( (v33 & 0xFFFFFFFFFFFFF000ui64) + ((v34 + 1) << 12) == v30 && v34 + 1 > v34 && v34 + 1 <= 0x3FF )
{
v83 = v25 + 1;
*v32 = ((unsigned __int16)v33 ^ (unsigned __int16)(v33 + 1)) & 0x3FF ^ (unsigned __int64)v33;
LABEL_82:
for( i = v21 + 8 * v22; v21 < i; v21 += 8i64 )
*(_QWORD *)v21 = 0i64;
if( v72 )
MiFlushTbList((__int64)&v81);
v17 = v65;
v18 = v61;
v3 = v76;
goto LABEL_87;
}
}
}
if( (v24 & 4) == 0 )
{
v35 = &Base + (unsigned int)(v12 - 1);
v36 = *v35;
if( (*v35 & 0xC00) == 0 && (v36 & 0xFFFFFFFFFFFFF000ui64) == v30 + 4096 )
{
v37 = *v35 & 0x3FF;
if( v37 + 1 > v37 && v37 + 1 <= 0x3FF )
{
v83 = v25 + 1;
*v35 = ((unsigned __int16)(v36 - 4096) ^ (unsigned __int16)(v36 - 4096 + 1)) & 0x3FF ^ (unsigned __int64)(v36 - 4096);
goto LABEL_82;
}
}
}
}
if( (unsigned int)v12 < (unsigned int)v82 )
{
while( 1 )
{
v38 = 1024i64;
if( (unsigned __int64)(v31 - 1) <= 0x3FF )
v38 = v31;
v31 -= v38;
v39 = v30 & 0xFFFFFFFFFFFFF000ui64 | ((_WORD)v38 - 1) & 0x3FF;
v30 += v38 << 12;
*(&Base + (unsigned int)v12) = v39;
v12 = (unsigned int)(HIDWORD(v82) + 1);
HIDWORD(v82) = v12;
v83 += v38;
if( (_DWORD)v12 == (_DWORD)v82 && (v81 & 0x400000000i64) == 0 )
{
qsort((WCHAR *)&Base, (unsigned int)v12, (const WCHAR *)8, MiTbFlushSort);
MiCompressTbFlushList((INT64)&v81);
v12 = HIDWORD(v82);
if( HIDWORD(v82) == (_DWORD)v82 )
{
if( v31 )
break;
}
}
if( !v31 )
goto LABEL_82;
}
BYTE5(v81) = 1;
v83 = HIDWORD(v82);
}
else
{
BYTE5(v81) = 1;
}
goto LABEL_82;
}
v19 = rcx0;
MiFreeUltraMapping(*(_QWORD *)(*(_QWORD *)(rcx0 + 224) + 176i64));
v17 = v65;
LABEL_88:
v43 = *(_QWORD *)&v67[1];
if( *(_QWORD *)&v67[1] && v73 == 1 )
*(_QWORD *)(v19 + 224) = 0i64;
v44 = v62;
if( v62 == 1 || P )
{
v45 = *(_BYTE *)(v17 + 71);
v46 = (RTL_BITMAP *)&dword_140C4E2B0;
if( v45 )
v46 = (RTL_BITMAP *)&dword_140C4E2A0;
v47 = (unsigned __int64 *)&RootPointer;
if( v45 )
v47 = (unsigned __int64 *)&qword_140C4E2A8;
*(_DWORD *)SpinCount = 0;
if( _interlockedbittestandset((volatile signed __int32 *)v46, 0x1Fu) )
{
LOBYTE(v44) = -1;
*(_DWORD *)SpinCount = ExpWaitForSpinLockExclusiveAndAcquire(v46, v44, (UINT64 *)v12);
}
SizeOfBitMap = v46->SizeOfBitMap;
while( (SizeOfBitMap & 0xBFFFFFFF) != 0x80000000 )
{
if( (SizeOfBitMap & 0x40000000) == 0 )
{
v50 = _InterlockedCompareExchange((volatile signed __int32 *)v46, SizeOfBitMap | 0x40000000, SizeOfBitMap);
v49 = SizeOfBitMap == v50;
SizeOfBitMap = v50;
if( !v49 )
continue;
}
KeYieldProcessorEx((UINT64 *)SpinCount);
SizeOfBitMap = v46->SizeOfBitMap;
}
RtlAvlRemoveNode(v47, (__int64 *)v65);
*(_BYTE *)(v65 + 68) = 0;
v46->SizeOfBitMap = 0;
LODWORD(v44) = v62;
v43 = *(_QWORD *)&v67[1];
}
v51 = *(_BYTE *)(v78 + 80);
if( v18 == 1 )
{
if( v51 )
++dword_140C2A098[(unsigned int)v79];
else
++dword_140C2A0D8[(unsigned int)v79];
++dword_140C2A074;
LABEL_110:
v52 = 0i64;
LABEL_111:
v53 = LargePageIndex;
goto LABEL_112;
}
if( v51 )
{
++dword_140C2A088[(unsigned int)v79];
}
else if( *(_BYTE *)(v65 + 70) )
{
++dword_140C2A0A8[(unsigned int)v79];
}
else
{
++dword_140C2A0C8[(unsigned int)v79];
}
++dword_140C2A068;
if( (_DWORD)v44 != 1 )
goto LABEL_110;
v52 = (v3 - (__int64)MmGetPfnDb()) / 48;
v53 = LargePageIndex;
if( LargePageIndex == 3 )
{
v54 = 1;
++dword_140C2A06C;
*(_QWORD *)(rcx0 + 24) = 0i64;
*(_BYTE *)(v3 + 34) &= ~8u;
v55 = 128i64;
if( qword_140C4DC80 )
{
if( (qword_140C4DC80 & 0x80) != 0 )
v55 = 144i64;
else
v55 = qword_140C4DC80 | 0x80;
}
*(_QWORD *)(v3 + 16) = v55;
if( *(_BYTE *)(v65 + 70) )
{
MiFreeListPageContentsChanged(v52);
}
else
{
if( v66 )
{
LODWORD(v56) = MiSearchNumaNodeTable((PVOID)v52);
v57 = *(_DWORD *)(v56 + 8);
v58 = ((unsigned int)MiGetPfnChannel(v3) << byte_140C4DBCD) | dword_140C4DC38 & (unsigned int)v52 | (v57 << byte_140C4DBCC);
if( MiFreeZeroPageSlistSufficient(*(INT64 *)&SpinCount[4], (unsigned int)v58, 0i64) )
{
if( *(_QWORD *)(*(_QWORD *)(*(_QWORD *)&SpinCount[4] + 2176i64) + 40 * v58) >= (unsigned __int64)(unsigned int)(4 * *(_DWORD *)(*(_QWORD *)&SpinCount[4] + 6300i64)) )
{
v54 = 1025;
LargePageIndex_4 = 1;
}
}
}
MiUnlinkFreeOrZeroedPage(v52, 0i64, 0i64);
MiInsertPageInFreeOrZeroedList(v52, v54);
}
goto LABEL_111;
}
v59 = 0;
if( v66 )
{
if( !*(_BYTE *)(v65 + 70) )
v59 = 1;
LargePageIndex_4 = v59;
}
MiLargePageFreeToZero(v52, LargePageIndex, v59);
LABEL_112:
_InterlockedAnd64((volatile signed __int64 *)(v3 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(CurrentIrql);
if( v43 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( P )
ExFreePoolWithTag(P, 0);
if( LargePageIndex_4 )
MiChangePageHeatImmediate(v52, v53, 0i64);
if( v66 )
{
v60 = *(_QWORD *)&SpinCount[4];
if( _InterlockedCompareExchange64((volatile signed __int64 *)(*(_QWORD *)&SpinCount[4] + 192i64), 0i64, 17i64) != 17 )
ExfReleasePushLockShared((INT64 *)(v60 + 192));
KeAbPostRelease((PVOID)(v60 + 192));
KiLeaveGuardedRegionUnsafe(CurrentThread);
MiSetZeroPageThreadPriority(v60, CurrentThread, v68);
}
}Referenced by:
MiZeroLargePages
MiZeroPageThread