MiUnlinkNodeLargePages
NTSTATUS __stdcall MiUnlinkNodeLargePages(
INT64 a1,
UINT64 a2,
INT64 a3,
UINT64 a4,
INT64 a5,
INT64 a6,
INT64 a7,
INT64 Channel,
UINT64 Node){
__int64 v9;
int v10;
_MI_NODE_INFORMATION *v11;
_MI_FREE_LARGE_PAGES *v12;
__int64 v13;
unsigned __int8 CurrentIrql;
unsigned int v15;
__int64 v16;
int v17;
unsigned int v18;
__int64 *v19;
__int64 v20;
char *LockedChannelOrdering;
char *v22;
CHAR v23;
unsigned int v24;
__int64 v25;
unsigned int v26;
__int64 v27;
__int64 *v28;
__int64 v29;
unsigned int v30;
__int64 v31;
_MI_FREE_LARGE_PAGE_LIST *v32;
__int64 v33;
__int64 v34;
unsigned int v35;
unsigned int v36;
unsigned int v37;
__int64 v38;
__int64 v39;
int v40;
INT64 *v41;
__int64 v42;
_BOOL4 v43;
unsigned int v44;
int v45;
INT64 v46;
_MMPFN *v47;
volatile signed __int64 *v48;
signed __int8 v49;
_BOOL4 v50;
INT64 **v51;
_QWORD *v52;
_RTL_BALANCED_NODE *v53;
bool v54;
char v55;
_MMPFN *v56;
_MMPFN *bf_0;
NTSTATUS v58;
INT64 v59;
_MMPFN *v60;
_MMPFN *v61;
UINT64 v63;
_BOOL4 v64;
unsigned int v65;
unsigned int v66;
_MI_FREE_LARGE_PAGES *v67;
__int64 v68;
UINT64 SpinCount;
__int64 v70;
__int64 v71;
_MMPFN *Pfn1;
__int64 v73;
__int64 v74;
_MI_NODE_INFORMATION *NodeInformation;
UINT64 Long;
_KLOCK_QUEUE_HANDLE LockHandle;
_MI_LARGE_PAGE_LISTS_CHANGING *LargeListWaiters;
int v79[2];
__int64 v80[2];
__int64 v81;
__int64 v82;
INT64 v83;
unsigned int LargePageIndex;
char v87;
char v88;
LargePageIndex = a2;
v9 = *(_QWORD *)(a1 + 16);
v10 = Channel;
memset(&LockHandle, 0, sizeof(LockHandle));
v11 = (_MI_NODE_INFORMATION *)(4544i64 * (unsigned int)a4 + v9);
v87 = 0;
v81 = 4544i64 * (unsigned int)a4;
NodeInformation = v11;
if( !v11->TotalPagesEntireNode && (MiFlags & 0x30) != 0 )
return 0;
v12 = &v11->FreeLargePages[(unsigned int)a2];
v83 = MiLargePageSizes[(unsigned int)a2];
HIDWORD(SpinCount) = *((_DWORD *)&stru_140C4DB30 + (unsigned int)a2 + 100);
v67 = v12;
if( (Channel & 4) != 0 )
v70 = 0x100000000i64;
else
v70 = 1i64;
v13 = (Channel & 1) == 0;
v71 = v13;
CurrentIrql = 17;
Pfn1 = 0i64;
v15 = ((Channel & 2) != 0) + 1;
v65 = v15;
while( 2 )
{
v16 = (int)a6;
v17 = 0;
while( 1 )
{
v18 = 0;
v19 = &v70;
do
{
v20 = *(int *)v19;
if( v12->LargePageFreeCountHiLow[0][v20] || v13 == 1 && v12->LargePageFreeCountHiLow[1][v20] )
break;
++v18;
v19 = (__int64 *)((char *)v19 + 4);
}
while( v18 < v15 );
if( v18 != v15 )
break;
if( v17 != 1 )
{
if( (v10 & 0x10) == 0 )
return 0;
goto LABEL_28;
}
if( !v11->LargeListMoveInProgress )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
return 0;
}
if( (v10 & 0x10) != 0 )
{
v79[1] = 0;
v80[1] = (__int64)v80;
v80[0] = (__int64)v80;
LargeListWaiters = v11->LargeListWaiters;
v11->LargeListWaiters = (_MI_LARGE_PAGE_LISTS_CHANGING *)&LargeListWaiters;
v79[0] = 393479;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
KeWaitForGate((_KGATE *)v79, WrVirtualMemory, v23);
}
else
{
LODWORD(SpinCount) = 0;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
if( Node || CurrentIrql != 2 )
return 0;
LODWORD(SpinCount) = 0;
while( v11->LargeListMoveInProgress )
KeYieldProcessorEx(&SpinCount);
}
v17 = 0;
LABEL_29:
v12 = v67;
v15 = v65;
v13 = v71;
}
if( !v17 )
{
LABEL_28:
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v17 = 1;
KeAcquireInStackQueuedSpinLockAtDpcLevel(&v11->LargePageLock, &LockHandle);
goto LABEL_29;
}
if( (_DWORD)a5 == 4 )
{
LockedChannelOrdering = (char *)v11->LockedChannelOrdering;
v22 = (char *)&v11->LockedChannelOrdering[MmNumberOfChannels];
}
else
{
v87 = a5;
LockedChannelOrdering = &v87;
v22 = &v88;
}
LABEL_31:
v24 = (unsigned __int8)*LockedChannelOrdering;
v25 = 0i64;
v66 = v24;
v68 = 0i64;
LABEL_32:
v26 = 0;
v27 = v24;
v28 = &v70;
LABEL_33:
v29 = *(int *)v28;
v30 = 0;
v73 = v16;
v31 = v27 + 4 * (v29 + 2 * v25);
while( 1 )
{
v32 = v67->LargePageEntries[0][0][v31][v16];
if( v67->LargePagesCount[0][0][v31][v16] )
break;
v33 = v16;
v34 = v16 + 1;
v16 = 0i64;
if( v33 != 3 )
v16 = v34;
++v30;
v73 = v16;
if( v30 > 3 )
{
v25 = v68;
++v26;
v28 = (__int64 *)((char *)v28 + 4);
v73 = v16;
v16 = (int)a6;
if( v26 < v65 )
goto LABEL_33;
v24 = v66;
v16 = (int)a6;
v25 = v68 + 1;
v68 = v25;
if( v25 <= v71 )
goto LABEL_32;
v16 = (int)a6;
++LockedChannelOrdering;
v68 = v25;
if( LockedChannelOrdering != v22 )
goto LABEL_31;
break;
}
}
v35 = LargePageIndex;
v36 = HIDWORD(SpinCount);
v37 = v66;
v38 = v73;
v39 = (unsigned int)(*(_DWORD *)(a7 + 4i64 * LargePageIndex) % HIDWORD(SpinCount));
v40 = v39;
v82 = v29;
v41 = (INT64 *)&v32[v39];
v42 = v73 + 4 * (v66 + 4 * (v29 + 2 * v68));
v74 = v42;
v43 = Node == 0;
while( 2 )
{
v64 = v43;
LABEL_43:
v44 = 0;
if( v36 )
{
do
{
if( (INT64 *)*v41 != v41 )
{
if( v64 || (*(_BYTE *)(v41[1] + 34) & 8) == 0 )
break;
v42 = v74;
}
v45 = v40 + 1;
if( v40 + 1 == v36 )
v41 = (INT64 *)v67->LargePageEntries[0][0][0][v42];
else
v41 += 3;
v40 = 0;
++v44;
if( v45 != v36 )
v40 = v45;
}
while( v44 < v36 );
v10 = Channel;
v38 = v73;
v43 = v64;
v42 = v74;
}
if( v44 == v36 )
{
if( v43 )
goto LABEL_85;
v43 = 1;
continue;
}
break;
}
v46 = v41[1];
v47 = Pfn1;
v48 = (volatile signed __int64 *)(v46 + 24);
v49 = _interlockedbittestandset64((volatile signed __int32 *)(v46 + 24), 0x3Fui64);
if( v47 )
{
if( v49 )
goto LABEL_81;
v50 = 1;
}
else
{
v50 = v49 == 0;
}
if( v50 )
{
if( Node )
{
v46 = v41[1];
v51 = *(INT64 ***)(v46 + 8);
if( *(INT64 **)v46 != v41
|| *v51 != (INT64 *)v46
|| (v41[1] = (INT64)v51, *v51 = v41, v52 = (_QWORD *)*v41, *(INT64 **)(*v41 + 8) != v41) )
{
__fastfail(3u);
}
v53 = (_RTL_BALANCED_NODE *)Node;
*(_QWORD *)v46 = v52;
*(_QWORD *)(v46 + 8) = v41;
v52[1] = v46;
*v41 = v46;
if( !MiBeginPageAccessor(v53, v46) )
LABEL_66:
v46 = 0i64;
}
else
{
LODWORD(v63) = v10;
if( !MiUnlinkNodeLargePageHelper(NodeInformation, (_MMPFN *)v46, v35, v37, v63) )
goto LABEL_66;
if( (v10 & 0x20) != 0 )
++*(_DWORD *)(v81 + *(_QWORD *)(a1 + 16) + 4284);
*(_QWORD *)v46 = Pfn1;
}
if( !v46 )
{
_InterlockedAnd64(v48, 0x7FFFFFFFFFFFFFFFui64);
break;
}
++v40;
v35 = LargePageIndex;
v55 = a3 - 1;
v54 = a3 == 1;
Pfn1 = (_MMPFN *)v46;
--a3;
*(_DWORD *)(a7 + 4i64 * LargePageIndex) = v40;
if( v54 )
break;
if( (v55 & 0xF) == 0 )
{
if( (unsigned int)KeShouldYieldProcessor() )
break;
v35 = LargePageIndex;
}
v36 = HIDWORD(SpinCount);
if( v40 == HIDWORD(SpinCount) )
{
v40 = 0;
v37 = v66;
v41 = (INT64 *)v67->LargePageEntries[v68][v82][v66][v38];
v43 = v64;
v42 = v74;
}
else
{
v43 = v64;
v41 += 3;
v42 = v74;
v37 = v66;
}
goto LABEL_43;
}
LABEL_81:
if( !v47 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
v11 = NodeInformation;
v12 = v67;
v15 = v65;
v13 = v71;
continue;
}
break;
}
LABEL_85:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
v56 = Pfn1;
if( !Pfn1 )
goto LABEL_91;
while( 2 )
{
if( Node )
{
bf_0 = 0i64;
goto LABEL_88;
}
bf_0 = (_MMPFN *)v56->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0;
if( v56->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 )
_InterlockedAnd64(&v56->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
else
LABEL_88:
MiUnlockPage(v56, 2u);
v56 = bf_0;
if( bf_0 )
continue;
break;
}
LOBYTE(v10) = Channel;
if( (Channel & 0x20) == 0 )
LABEL_91:
__writecr8(CurrentIrql);
v58 = (int)Pfn1;
if( Pfn1 && (v10 & 0x40) == 0 && (_DWORD)a6 != *((unsigned __int8 *)&Pfn1->u3 + 2) >> 6 )
{
v59 = v83;
v60 = Pfn1;
do
{
if( Node )
v61 = 0i64;
else
v61 = (_MMPFN *)v60->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0;
MiChangePageAttributeContiguous(v60 - MmGetPfnDb(), v59, (unsigned int)a6);
Long = v60->OriginalPte.u.Long;
MiSetOriginalPtePfnFromFreeList(&Long);
v60->OriginalPte.u.Long = Long;
v60 = v61;
}
while( v61 );
}
return v58;
}Referenced by:
MiGetFreeZeroLargePages
MiGetHugePageToZero
MiGetPagesToZero
MiScrubNodeLargePageList
MiTimeSingleLargePageZeroWorker
MiZeroLargePages