MiUnlinkNodeLargePages
INT64 __fastcall MiUnlinkNodeLargePages(
INT64 a1,
UINT64 a2,
INT64 a3,
UINT64 a4,
INT64 a5,
INT64 a6,
INT64 a7,
INT64 a8,
UINT64 a9){
__int64 v9;
char v10;
UINT8 v11;
_MI_NODE_INFORMATION *v12;
char *v13;
__int64 v14;
unsigned __int8 CurrentIrql;
unsigned int v16;
__int64 v17;
int v18;
unsigned int v19;
__int64 *v20;
__int64 v21;
char *v22;
char *v23;
unsigned int v24;
__int64 v25;
unsigned int v26;
__int64 v27;
__int64 *v28;
__int64 v29;
unsigned int v30;
__int64 v31;
__int64 v32;
__int64 v33;
__int64 v34;
unsigned int v35;
unsigned int v36;
unsigned int v37;
__int64 v38;
__int64 v39;
int v40;
INT64 *v41;
__int64 v42;
BOOL v43;
unsigned int v44;
int v45;
INT64 v46;
_MMPFN *v47;
volatile signed __int64 *v48;
signed __int8 v49;
BOOL v50;
INT64 **v51;
_QWORD *v52;
RTL_BALANCED_NODE *v53;
bool v54;
char v55;
_MMPFN *v56;
_MMPFN *v57;
_MMPFN *v58;
INT64 v59;
_MMPFN *v60;
_MMPFN *v61;
BOOL v63;
unsigned int v64;
unsigned int Channel;
char *v66;
__int64 v67;
UINT64 SpinCount;
__int64 v69;
__int64 v70;
_MMPFN *Pfn1;
__int64 v72;
__int64 v73;
_MI_NODE_INFORMATION *NodeInformation;
UINT64 v75;
struct _KLOCK_QUEUE_HANDLE LockHandle;
__int64 v77;
int PcValue[2];
__int64 v79[2];
__int64 v80;
__int64 v81;
INT64 v82;
unsigned int LargePageIndex;
char v86;
char v87;
LargePageIndex = a2;
v9 = *(_QWORD *)(a1 + 16);
v10 = a8;
memset(&LockHandle, 0, sizeof(LockHandle));
v11 = a2;
v12 = (_MI_NODE_INFORMATION *)(4544i64 * (unsigned int)a4 + v9);
v86 = 0;
v80 = 4544i64 * (unsigned int)a4;
NodeInformation = v12;
if( !*((_QWORD *)v12 + 522) && (MiFlags & 0x30) != 0 )
return 0i64;
v13 = (char *)v12 + 1072 * (unsigned int)a2;
v82 = MiLargePageSizes[(unsigned int)a2];
HIDWORD(SpinCount) = dword_140C4DCC0[(unsigned int)a2];
v66 = v13;
if( (a8 & 4) != 0 )
v69 = 0x100000000i64;
else
v69 = 1i64;
v14 = (a8 & 1) == 0;
v70 = v14;
CurrentIrql = 17;
Pfn1 = 0i64;
v16 = ((a8 & 2) != 0) + 1;
v64 = v16;
while( 2 )
{
v17 = (int)a6;
v18 = 0;
while( 1 )
{
v19 = 0;
v20 = &v69;
do
{
v21 = *(int *)v20;
if( *(_QWORD *)&v13[8 * v21 + 16] || v14 == 1 && *(_QWORD *)&v13[8 * v21 + 32] )
break;
++v19;
v20 = (__int64 *)((char *)v20 + 4);
}
while( v19 < v16 );
if( v19 != v16 )
break;
if( v18 != 1 )
{
if( (v10 & 0x10) == 0 )
return 0i64;
goto LABEL_28;
}
if( !*((_DWORD *)v12 + 1071) )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
return 0i64;
}
if( (v10 & 0x10) != 0 )
{
PcValue[1] = 0;
v79[1] = (__int64)v79;
v79[0] = (__int64)v79;
v77 = *((_QWORD *)v12 + 536);
*((_QWORD *)v12 + 536) = &v77;
PcValue[0] = 393479;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
KeWaitForGate(PcValue, 18);
}
else
{
LODWORD(SpinCount) = 0;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
v11 = 2;
__writecr8(CurrentIrql);
if( a9 || CurrentIrql != 2 )
return 0i64;
LODWORD(SpinCount) = 0;
while( *((_DWORD *)v12 + 1071) )
KeYieldProcessorEx(&SpinCount);
}
v18 = 0;
LABEL_29:
v13 = v66;
v16 = v64;
v14 = v70;
}
if( !v18 )
{
LABEL_28:
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v18 = 1;
KeAcquireInStackQueuedSpinLockAtDpcLevel((UINT64 *)v12 + 541, &LockHandle, v11);
goto LABEL_29;
}
if( (_DWORD)a5 == 4 )
{
v22 = (char *)v12 + 4317;
v23 = (char *)v12 + (unsigned int)MmNumberOfChannels + 4317;
}
else
{
v86 = a5;
v22 = &v86;
v23 = &v87;
}
LABEL_31:
v24 = (unsigned __int8)*v22;
v25 = 0i64;
Channel = v24;
v67 = 0i64;
LABEL_32:
v26 = 0;
v27 = v24;
v28 = &v69;
LABEL_33:
v29 = *(int *)v28;
v30 = 0;
v72 = v17;
v31 = v27 + 4 * (v29 + 2 * v25);
while( 1 )
{
v32 = *(_QWORD *)&v66[32 * v31 + 560 + 8 * v17];
if( *(_QWORD *)&v66[32 * v31 + 48 + 8 * v17] )
break;
v33 = v17;
v34 = v17 + 1;
v17 = 0i64;
if( v33 != 3 )
v17 = v34;
++v30;
v72 = v17;
if( v30 > 3 )
{
v25 = v67;
++v26;
v28 = (__int64 *)((char *)v28 + 4);
v72 = v17;
v17 = (int)a6;
if( v26 < v64 )
goto LABEL_33;
v24 = Channel;
v17 = (int)a6;
v25 = v67 + 1;
v67 = v25;
if( v25 <= v70 )
goto LABEL_32;
v17 = (int)a6;
++v22;
v67 = v25;
if( v22 != v23 )
goto LABEL_31;
break;
}
}
v35 = LargePageIndex;
v36 = HIDWORD(SpinCount);
v37 = Channel;
v38 = v72;
v39 = (unsigned int)(*(_DWORD *)(a7 + 4i64 * LargePageIndex) % HIDWORD(SpinCount));
v40 = v39;
v81 = v29;
v41 = (INT64 *)(v32 + 24 * v39);
v42 = v72 + 4 * (Channel + 4 * (v29 + 2 * v67));
v73 = v42;
v43 = a9 == 0;
while( 2 )
{
v63 = v43;
LABEL_43:
v44 = 0;
if( v36 )
{
do
{
if( (INT64 *)*v41 != v41 )
{
if( v63 || (*(_BYTE *)(v41[1] + 34) & 8) == 0 )
break;
v42 = v73;
}
v45 = v40 + 1;
if( v40 + 1 == v36 )
v41 = *(INT64 **)&v66[8 * v42 + 560];
else
v41 += 3;
v40 = 0;
++v44;
if( v45 != v36 )
v40 = v45;
}
while( v44 < v36 );
v10 = a8;
v38 = v72;
v43 = v63;
v42 = v73;
}
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( a9 )
{
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 *)a9;
*(_QWORD *)v46 = v52;
*(_QWORD *)(v46 + 8) = v41;
v52[1] = v46;
*v41 = v46;
if( !(unsigned int)MiBeginPageAccessor(v53, v46) )
LABEL_66:
v46 = 0i64;
}
else
{
if( !MiUnlinkNodeLargePageHelper(NodeInformation, (_MMPFN *)v46, v35, v37) )
goto LABEL_66;
if( (v10 & 0x20) != 0 )
++*(_DWORD *)(v80 + *(_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( KeShouldYieldProcessor() )
break;
v35 = LargePageIndex;
}
v36 = HIDWORD(SpinCount);
if( v40 == HIDWORD(SpinCount) )
{
v40 = 0;
v37 = Channel;
v41 = *(INT64 **)&v66[256 * v67 + 560 + 128 * v81 + 32 * Channel + 8 * v38];
v43 = v63;
v42 = v73;
}
else
{
v43 = v63;
v41 += 3;
v42 = v73;
v37 = Channel;
}
goto LABEL_43;
}
LABEL_81:
if( !v47 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
v12 = NodeInformation;
v13 = v66;
v16 = v64;
v14 = v70;
continue;
}
break;
}
LABEL_85:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
v56 = Pfn1;
if( !Pfn1 )
goto LABEL_91;
while( 2 )
{
if( a9 )
{
v57 = 0i64;
goto LABEL_88;
}
v57 = *(_MMPFN **)v56;
if( *(_QWORD *)v56 )
_InterlockedAnd64((volatile signed __int64 *)v56 + 3, 0x7FFFFFFFFFFFFFFFui64);
else
LABEL_88:
MiUnlockPage(v56, 2u);
v56 = v57;
if( v57 )
continue;
break;
}
v10 = a8;
if( (a8 & 0x20) == 0 )
LABEL_91:
__writecr8(CurrentIrql);
v58 = Pfn1;
if( Pfn1 && (v10 & 0x40) == 0 && (_DWORD)a6 != *((unsigned __int8 *)Pfn1 + 34) >> 6 )
{
v59 = v82;
v60 = Pfn1;
do
{
if( a9 )
v61 = 0i64;
else
v61 = *(_MMPFN **)v60;
MiChangePageAttributeContiguous((v60 - MmGetPfnDb()) / 48, v59, (unsigned int)a6);
v75 = *((_QWORD *)v60 + 2);
MiSetOriginalPtePfnFromFreeList(&v75);
*((_QWORD *)v60 + 2) = v75;
v60 = v61;
}
while( v61 );
}
return(INT64)v58;
}Referenced by:
MiGetFreeZeroLargePages
MiGetHugePageToZero
MiGetPagesToZero
MiScrubNodeLargePageList
MiTimeSingleLargePageZeroWorker
MiZeroLargePages