MiZeroLargePages
NTSTATUS __stdcall MiZeroLargePages(_MI_ZERO_THREAD_CONTEXT *ThreadContext){
_MI_ZERO_THREAD_CONTEXT *v1;
_ETHREAD *v2;
NTSTATUS v3;
__int64 v4;
unsigned int v5;
__int64 v6;
INT64 v7;
__int64 v8;
volatile __int32 *v9;
unsigned __int64 v10;
__int64 v11;
int v12;
__int64 v13;
bool v14;
__int64 v15;
unsigned __int8 CurrentIrql;
_ETHREAD *v17;
NTSTATUS result;
PHYSICAL_MEMORY_DESCRIPTOR *v19;
__int64 v20;
__int64 v21;
NTSTATUS HugePageToZero;
UINT64 v23;
_MMPFN *v24;
_MMPFN *v25;
int v26;
int v27;
_MI_ZERO_THREAD_CONTEXT v28;
unsigned int v29;
__int64 v30;
unsigned __int64 v31;
int v32;
int v33;
char v34;
INT64 *v35;
_ETHREAD *CurrentThread;
char v37;
signed __int32 v38;
signed __int32 v39;
_RTL_BALANCED_NODE *v40;
bool v41;
_RTL_BALANCED_NODE *v43;
$2AC33BEB5BE0E2B4BDE1FE63E3EEE4EC *v44;
__int8 bf_0;
char v46;
char i;
unsigned int v48;
__int64 v49;
_RTL_BALANCED_NODE **v50;
unsigned __int64 v51;
_RTL_BALANCED_NODE *v52;
unsigned __int64 ParentValue;
unsigned __int64 v54;
_RTL_BALANCED_NODE *v55;
__int64 v56;
__int8 v57;
_QWORD *v58;
BOOL v59;
__int64 v60;
__int64 v61;
__int64 v62;
__int64 v63;
volatile signed __int32 *v64;
signed __int32 v65[8];
PLARGE_INTEGER Timeout;
INT64 v67;
INT64 v68;
__int64 v69;
_KLOCK_QUEUE_HANDLE LockHandle;
volatile signed __int32 *v71;
INT64 v72;
unsigned __int64 v73;
__int64 v74;
__int64 v75;
_ETHREAD *Thread;
_GROUP_AFFINITY Affinity;
unsigned int v79;
UINT64 SpinCount;
INT64 NewBase;
v1 = ThreadContext;
Thread = (_ETHREAD *)KeGetCurrentThread();
v2 = Thread;
Thread->SameThreadPassiveFlags |= 0x400u;
v3 = KeSetActualBasePriorityThread(&v2->Tcb, 0i64);
v5 = 0;
v6 = *((_QWORD *)v1 + 29);
LODWORD(NewBase) = v3;
v79 = 0;
v75 = v6;
v7 = *(_QWORD *)(v6 + 72);
*((_QWORD *)v1 + 34) = KeGetCurrentThread();
v8 = (unsigned int)v1[66];
v72 = v7;
*(_QWORD *)(*(_QWORD *)(v6 + 144) + 40 * v8 + 8) = v1;
v9 = (volatile __int32 *)(*(_QWORD *)(v6 + 144) + 40i64 * (unsigned int)v1[66]);
_InterlockedExchange(v9, 0);
v71 = v9;
v10 = __rdtsc();
_InterlockedOr(v65, 0);
while( 2 )
{
v73 = v10;
LABEL_3:
v11 = *((_QWORD *)v1 + 29);
memset(&LockHandle, 0, sizeof(LockHandle));
v12 = 0;
v13 = *(_QWORD *)(v11 + 72);
if( *(_DWORD *)(v11 + 136) )
{
v15 = *(_QWORD *)(v11 + 144) + 40i64 * (unsigned int)v1[66];
if( (*(_BYTE *)(v15 + 4) & 1) != 0 )
{
while( 1 )
{
LockHandle.LockQueue.Lock = (unsigned __int64 *volatile)(v11 + 24);
LockHandle.LockQueue.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.OldIrql = CurrentIrql;
KxAcquireQueuedSpinLock(&LockHandle.LockQueue, (UINT64 *)(v11 + 24));
if( (*(_BYTE *)(v15 + 4) & 2) != 0 || (*(_BYTE *)(v15 + 4) & 1) == 0 )
break;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v12 = 1;
KeWaitForSingleObject(v15 + 16, 0, 0, 0, 0i64);
if( (*(_BYTE *)(v15 + 4) & 1) == 0 )
goto LABEL_14;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
LABEL_14:
v9 = v71;
}
while( *(_DWORD *)(v13 + 6340) || *(&stru_140C4DB30 + 1082) )
{
if( !KeWaitForSingleObject(v13 + 104, 8, 0, 0, (INT64)&unk_140010580) )
{
KeSetActualBasePriorityThread(KeGetCurrentThread(), 12i64);
LABEL_19:
++dword_140C2A048;
goto LABEL_20;
}
}
v5 = v79;
}
else if( !*((_BYTE *)v1 + 300) )
{
*((_BYTE *)v1 + 300) = 1;
KeAcquireInStackQueuedSpinLock((PKSPIN_LOCK)(v11 + 24), &LockHandle);
v14 = (*(_DWORD *)(v11 + 152))-- == 1;
if( v14 )
*(_DWORD *)(v11 + 136) = 1;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( !*((_QWORD *)v1 + 30) )
{
v19 = MiReferencePageRuns(*(ULONG_PTR **)(v11 + 72), 0i64);
if( !v19 )
goto LABEL_19;
*((_QWORD *)v1 + 30) = v19;
}
if( v12 )
{
_InterlockedExchange(v9, 0);
v73 = __rdtsc();
_InterlockedOr(v65, 0);
}
v20 = v75;
++*(_DWORD *)(v75 + 288);
if( !v5 && *((_BYTE *)v1 + 80) )
{
v21 = v72;
HugePageToZero = MiGetHugePageToZero(v72, (INT64)v1);
goto LABEL_117;
}
v23 = (unsigned int)v1[65] >> *(&stru_140C4DB30 + 156);
*((_QWORD *)v1 + 4) = 0i64;
*((_BYTE *)v1 + 69) = 0;
if( v5 < 3 )
{
v21 = v72;
LODWORD(v68) = 64;
LODWORD(v67) = 1;
LODWORD(Timeout) = 4;
LODWORD(v24) = MiUnlinkNodeLargePages(v72, v5, 1i64, v23, (INT64)Timeout, v67, (INT64)(v1 + 62), v68, (UINT64)v1);
v25 = v24;
goto LABEL_112;
}
v26 = 0;
LOBYTE(v4) = 17;
v27 = 0;
v69 = v4;
v28 = ThreadContext[65];
v29 = v28;
v30 = *(_QWORD *)(v72 + 2184);
v74 = v30;
while( 1 )
{
v31 = *(_QWORD *)(v30 + 40i64 * v29 + 16);
if( v31 != 0xFFFFFFFFFi64 )
{
v25 = &MmGetPfnDb()[v31];
if( v27 || v25->u2._bf_0 >= 0 )
{
if( !v25 )
goto LABEL_38;
v4 = KeGetCurrentIrql();
v69 = v4;
__writecr8(2ui64);
v33 = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)&v25->u2, 0x3Fui64) )
{
do
{
do
{
++v33;
_mm_pause();
}
while( v25->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v25->u2, 0x3Fui64) );
v4 = v69;
}
if( v31 > 0xFFFFFFFFFi64
|| (MmGetPfnDb()[v31].u4._bf_0 & 0x4000000000000i64) == 0
|| (v34 = *((_BYTE *)&v25->u3 + 2), (v34 & 7) != 1)
|| (v25->u4._bf_0 & 0x1000000000i64) != 0 )
{
_InterlockedAnd64(&v25->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8((unsigned __int8)v4);
v25 = 0i64;
v29 = ThreadContext[65];
goto LABEL_39;
}
if( (v34 & 8) == 0 )
break;
_InterlockedAnd64(&v25->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8((unsigned __int8)v4);
}
else
{
v26 = 1;
}
}
v25 = 0i64;
LABEL_38:
v29 = *(&stru_140C4DB30 + 36) & (ThreadContext[65] + 1) | ThreadContext[65] & ~*(&stru_140C4DB30 + 36);
ThreadContext[65] = v29;
LABEL_39:
v30 = v74;
if( v29 == v28 )
{
if( !v26 )
break;
if( (unsigned int)++v27 >= 2 )
break;
}
}
if( !v25 )
{
v5 = v79;
break;
}
if( v25->u3.ReferenceCount )
KeBugCheckEx(
0x4Eu,
(PVOID)0x8D,
(PVOID)v31,
(PVOID)*(unsigned int *)&v25->u3.ReferenceCount,
v25->ListEntry.Blink);
v1 = ThreadContext;
if( (*(_BYTE *)(&v25->u3 + 1) & 8) != 0 )
{
v32 = 0;
goto LABEL_110;
}
*((_QWORD *)ThreadContext + 3) = v25;
v35 = (INT64 *)((char *)&stru_140C4DB30 + 1920);
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
*((_QWORD *)ThreadContext + 7) = CurrentThread;
v37 = *((_BYTE *)&v25->u3 + 2) | 8;
v25->OriginalPte.u.Long = (unsigned __int64)ThreadContext;
*((_BYTE *)&v25->u3 + 2) = v37;
v14 = *((_BYTE *)ThreadContext + 71) == 0;
*((_QWORD *)ThreadContext + 4) = 0i64;
if( !v14 )
v35 = (INT64 *)((char *)&stru_140C4DB30 + 1904);
*(_WORD *)((char *)ThreadContext + 69) = 0;
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset((volatile signed __int32 *)v35, 0x1Fu) )
LODWORD(SpinCount) = ExpWaitForSpinLockExclusiveAndAcquire(v35, 0xFFu);
v38 = *(_DWORD *)v35;
while( (v38 & 0xBFFFFFFF) != 0x80000000 )
{
if( (v38 & 0x40000000) == 0 )
{
v39 = _InterlockedCompareExchange((volatile signed __int32 *)v35, v38 | 0x40000000, v38);
v14 = v38 == v39;
v38 = v39;
if( !v14 )
continue;
}
KeYieldProcessorEx(&SpinCount);
v38 = *(_DWORD *)v35;
}
if( *((_BYTE *)ThreadContext + 71) )
{
v58 = (_QWORD *)*(&stru_140C4DB30 + 239);
v59 = 0;
if( *(&stru_140C4DB30 + 239) )
{
while( 1 )
{
while( (unsigned __int64)CurrentThread < v58[7] )
{
if( !*v58 )
goto LABEL_108;
v58 = (_QWORD *)*v58;
}
if( !v58[1] )
break;
v58 = (_QWORD *)v58[1];
}
v59 = 1;
}
LABEL_108:
RtlAvlInsertNodeEx(
(_RTL_BALANCED_NODE **)&stru_140C4DB30 + 239,
(UINT64)v58,
v59,
(_RTL_BALANCED_NODE *)ThreadContext);
goto LABEL_109;
}
v40 = (_RTL_BALANCED_NODE *)*(&stru_140C4DB30 + 241);
v41 = 0;
if( *(&stru_140C4DB30 + 241) )
{
while( 1 )
{
while( ThreadContext < (_MI_ZERO_THREAD_CONTEXT *)v40 )
{
if( !v40->Children[0] )
goto LABEL_75;
v40 = v40->Children[0];
}
if( !v40->Children[1] )
break;
v40 = v40->Children[1];
}
v41 = 1;
}
LABEL_75:
*(_QWORD *)ThreadContext = 0i64;
v43 = (_RTL_BALANCED_NODE *)ThreadContext;
*((_QWORD *)ThreadContext + 1) = 0i64;
*((_QWORD *)ThreadContext + 2) = v40;
if( v40 )
{
v44 = &v40->16;
v40->Children[v41] = (_RTL_BALANCED_NODE *)ThreadContext;
bf_0 = v40->_bf_0;
v46 = (-1 - 2 * v41) & 3;
for( i = bf_0 & 3; (bf_0 & 3) == 0; i = bf_0 & 3 )
{
v43 = v40;
v44->_bf_0 = v46 | bf_0 & 0xFC;
v40 = (_RTL_BALANCED_NODE *)(v44->ParentValue & 0xFFFFFFFFFFFFFFFCui64);
if( !v40 )
goto LABEL_109;
v44 = &v40->16;
bf_0 = v40->_bf_0;
v41 = v40->Children[0] != v43;
v46 = (-1 - 2 * v41) & 3;
}
if( i != v46 )
{
v40->_bf_0 &= 0xFCu;
goto LABEL_109;
}
if( (v43->_bf_0 & 3) != i )
{
v55 = RtlpTreeDoubleRotateNodes((_RTL_BALANCED_NODE **)&stru_140C4DB30 + 241, v40, v43, v41);
*(_BYTE *)(v56 + 16) &= 0xFCu;
v57 = v43->_bf_0 & 0xFC;
v43->_bf_0 = v57;
if( i == (v55->_bf_0 & 3) )
{
*(_BYTE *)(v56 + 16) ^= (*(_BYTE *)(v56 + 16) ^ i ^ 0xFE) & 3;
v55->_bf_0 &= 0xFCu;
}
else
{
if( i == ((v55->_bf_0 ^ 0xFE) & 3) )
v43->_bf_0 = v57 | i;
v55->_bf_0 &= 0xFCu;
}
goto LABEL_109;
}
v48 = !v41;
if( (_RTL_BALANCED_NODE *)(v43->ParentValue & 0xFFFFFFFFFFFFFFFCui64) == v40 )
{
v49 = v48;
v50 = &v40->Children[v48 ^ 1i64];
if( *v50 == v43 )
{
v51 = v40->ParentValue & 0xFFFFFFFFFFFFFFFCui64;
if( v51 )
{
if( *(_RTL_BALANCED_NODE **)(v51 + 8) == v40 )
{
*(_QWORD *)(v51 + 8) = v43;
}
else
{
if( *(_RTL_BALANCED_NODE **)v51 != v40 )
goto LABEL_128;
*(_QWORD *)v51 = v43;
}
}
else
{
if( (_RTL_BALANCED_NODE *)*(&stru_140C4DB30 + 241) != v40 )
goto LABEL_128;
*(&stru_140C4DB30 + 241) = v43;
}
v43->ParentValue = v51 | *(_DWORD *)&v43->_bf_0 & 3;
v52 = v43->Children[v49];
if( !v52 )
{
LABEL_95:
*v50 = v52;
v43->Children[v49] = v40;
v54 = (unsigned __int64)v43 | *(_DWORD *)&v40->_bf_0 & 3;
v40->ParentValue = v54;
v43->_bf_0 &= 0xFCu;
v40->_bf_0 &= 0xFCu;
goto LABEL_109;
}
ParentValue = v52->ParentValue;
if( (_RTL_BALANCED_NODE *)(ParentValue & 0xFFFFFFFFFFFFFFFCui64) == v43 )
{
v52->ParentValue = (unsigned __int64)v40 | ParentValue & 3;
goto LABEL_95;
}
}
}
LABEL_128:
__fastfail(0x1Du);
}
*(&stru_140C4DB30 + 241) = ThreadContext;
LABEL_109:
*((_BYTE *)ThreadContext + 68) = 1;
*(_DWORD *)v35 = 0;
v4 = v69;
v32 = 1;
LABEL_110:
_InterlockedAnd64(&v25->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8((unsigned __int8)v69);
v5 = v79;
if( v32 )
{
v21 = v72;
v20 = v75;
LABEL_112:
if( v25 )
{
if( !*((_BYTE *)v1 + 80) )
{
LODWORD(v60) = MiSearchNumaNodeTable((PVOID)(v25 - MmGetPfnDb()));
v61 = *(unsigned int *)(v60 + 8);
if( v1[67] != (_DWORD)v61 )
{
v1[67] = v61;
Affinity = *(_GROUP_AFFINITY *)(4544 * v61 + *(_QWORD *)(v21 + 16) + 4472);
MiSetIdealProcessorThread(&Affinity);
}
}
HugePageToZero = MiMapPagesToZero(v1, v25, v5);
LABEL_117:
if( HugePageToZero )
{
MiZeroPage((__int64)v1, v21);
if( v5 == 3 )
{
v62 = 1i64;
}
else
{
v63 = v5;
if( !v5 )
v63 = 1i64;
v62 = MiLargePageSizes[v63];
}
_InterlockedExchangeAdd64((volatile signed __int64 *)(v20 + 40), v62);
v9 = v71;
v64 = v71;
_InterlockedExchangeAdd(v71, v62);
if( *v64 >= 0x1000u )
{
_InterlockedOr(v65, 0);
MiReassessZeroThreads(v1, __rdtsc() - v73);
_InterlockedExchange(v9, 0);
v10 = __rdtsc();
_InterlockedOr(v65, 0);
continue;
}
goto LABEL_3;
}
}
}
break;
}
if( v5 < 3 )
{
v1 = ThreadContext;
++v5;
v9 = v71;
v79 = v5;
goto LABEL_3;
}
LABEL_20:
v17 = Thread;
result = KeSetActualBasePriorityThread(&Thread->Tcb, (unsigned int)NewBase);
v17->SameThreadPassiveFlags &= ~0x400u;
return result;
}Referenced by:
MiZeroLargePageThread