MiScrubNodeLargePageList
NTSTATUS __stdcall MiScrubNodeLargePageList(
_MI_PARTITION *Partition,
UINT64 PreferredNode,
UINT64 LargePageIndex,
_MI_MEMORY_HIGHLOW MemoryType,
_MMLISTS PageType,
UINT64 Channel,
UINT64 *NumberOfPages,
VOID *OpaqueParameter,
_KEVENT *StopEvent){
__int64 v9;
__int64 v10;
_ETHREAD *CurrentThread;
UINT64 v12;
int v13;
__int64 v14;
_MMLISTS v15;
UINT64 v16;
__int64 v18;
__int64 v19;
int v20;
_QWORD *v21;
unsigned int v22;
__int64 v23;
unsigned __int8 CurrentIrql;
int v25;
unsigned __int64 v26;
UINT64 v27;
unsigned int v28;
NTSTATUS v29;
unsigned int v30;
_MMPFN *v31;
_MMPFN *v32;
__int64 v33;
UINT8 v34;
unsigned __int64 v35;
_MI_LIST_THREAD_CONTEXT *v36;
unsigned __int64 v37;
__int64 v38;
__int64 v39;
_MMPTE *PteBase;
int v41;
INT64 v42;
INT64 v43;
unsigned __int64 v44;
unsigned __int64 v45;
int v46;
UINT64 v47;
unsigned __int64 v48;
int v49;
_MMPFN *v50;
_MMPFN *v51;
_MMPFN *v52;
_MMPFN *v53;
NTSTATUS v54;
UINT8 v55;
char v56;
bool v57;
int v58;
unsigned __int64 v59;
__int64 v60;
unsigned __int64 v61;
UINT64 v62;
INT64 v63;
INT64 v64;
INT64 v65;
UINT8 v66;
UINT8 v67;
unsigned int LargePageIndexa;
_MI_LIST_THREAD_CONTEXT *ThreadContext;
int v70;
int v71;
UINT64 NumberOfPtes;
__int64 Pfn1;
unsigned __int8 v74;
__int64 v75;
unsigned int v76;
int v77;
unsigned int v78;
_MMPFN *WorkPage;
_MMPFN *v80;
_MMPFN *v81;
_LARGE_INTEGER StartAddress;
UINT64 SpinCount;
int v84;
int v85;
INT64 v86;
unsigned __int64 v87;
__int64 *v88;
_QWORD *v89;
_QWORD *v90;
INT64 v91;
__int64 v92;
_MMPFN *v93;
unsigned __int64 v94;
_LARGE_INTEGER NumberOfBytes;
unsigned __int64 v96;
_QWORD *v97;
_ETHREAD *v98;
__int128 v99;
__int64 v100;
__int64 v101;
__int64 v102;
_MI_PARTITION *v103;
unsigned __int64 v104;
volatile signed __int64 *p_Lock;
unsigned __int64 v106;
unsigned __int64 v107;
char v108[80];
INT64 v109[2];
__int64 v110;
v9 = MemoryType;
LargePageIndexa = LargePageIndex;
v10 = (unsigned int)PreferredNode;
v77 = PreferredNode;
v91 = (INT64)Partition;
v103 = Partition;
v84 = PreferredNode;
v85 = LargePageIndex;
v88 = (__int64 *)OpaqueParameter;
v86 = (INT64)StopEvent;
v92 = v110;
memset(v108, 0i64, 0x48u);
*(_OWORD *)v109 = 0i64;
NumberOfBytes.QuadPart = 0i64;
StartAddress.QuadPart = 0i64;
v99 = 0i64;
v100 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v98 = CurrentThread;
Pfn1 = 0i64;
v12 = 0i64;
v13 = 64;
v14 = MiLargePageSizes[LargePageIndexa];
NumberOfPtes = v14;
v101 = v14;
v15 = PageType;
if( PageType )
{
ThreadContext = (_MI_LIST_THREAD_CONTEXT *)v108;
v108[71] = 1;
LOBYTE(v12) = LargePageIndexa <= 1;
if( LargePageIndexa > 1 )
{
v16 = (UINT64)MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), (unsigned int)v14);
v12 = v16;
if( !v16 )
return 1;
Pfn1 = (__int64)((v16 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
v15 = PageType;
CurrentThread = v98;
}
}
else
{
ThreadContext = 0i64;
}
v18 = *(_QWORD *)(v91 + 16) + 4544 * v10;
v74 = 17;
v94 = *v88;
v104 = v94;
v107 = v94;
v106 = v94;
*v88 = 0i64;
v87 = 0i64;
v96 = 0i64;
CurrentThread->SameThreadPassiveFlags |= 0x100u;
v76 = *((_DWORD *)&stru_140C4DB30 + LargePageIndexa + 100);
HIDWORD(SpinCount) = v76;
v19 = (int)v15 + 2 * v9;
v20 = Channel;
v21 = *(_QWORD **)(v18
+ 1072i64 * LargePageIndexa
+ 8 * ((int)NumberOfPages + 4 * ((unsigned int)Channel + 4 * v19))
+ 560);
v22 = 0;
while( 1 )
{
v78 = v22;
v97 = v21;
v90 = v21;
if( v22 >= v76 )
break;
v23 = v21[2];
v75 = v23;
v89 = v21;
CurrentIrql = v74;
while( v23 && (_QWORD *)*v21 != v21 )
{
LOBYTE(v25) = MiScrubInterrupted(v86);
if( v25 )
{
v29 = 0;
v30 = NumberOfPtes;
goto LABEL_82;
}
if( v15 )
{
v13 &= ~4u;
v70 = v13;
}
else
{
v13 |= 4u;
v70 = v13;
CurrentIrql = KeGetCurrentIrql();
v74 = CurrentIrql;
__writecr8(v26);
}
if( v27 )
*(_QWORD *)(v27 + 32) = 0i64;
LODWORD(v65) = v13;
LODWORD(v64) = (_DWORD)NumberOfPages;
LODWORD(v63) = v20;
LODWORD(v31) = MiUnlinkNodeLargePages(v91, v28, 1i64, (unsigned int)v10, v63, v64, (INT64)v109, v65, v27);
v32 = v31;
WorkPage = v31;
if( !v31 )
{
v15 = PageType;
if( PageType == ZeroedPageList )
__writecr8(CurrentIrql);
v20 = Channel;
break;
}
if( PageType )
{
v34 = MiLockPageInline(v31);
v35 = v34;
v66 = v34;
v36 = ThreadContext;
if( *((_BYTE *)ThreadContext + 69) == 1 )
{
MiRemoveFaultNode(ThreadContext);
_InterlockedAnd64(&v32->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v35);
CurrentIrql = v74;
}
else
{
if( LargePageIndexa > 1 )
{
v38 = Pfn1;
}
else
{
MiGetUltraMapping((_MI_ZERO_THREAD_CONTEXT *)(v92 + 32i64 * LargePageIndexa), LargePageIndexa);
v38 = v37;
Pfn1 = v37;
v12 = (UINT64)MmGetPdeBase() + ((v37 >> 18) & 0x3FFFFFF8);
if( !LargePageIndexa )
{
v39 = 1i64;
PteBase = MmGetPteBase();
do
{
v12 = (UINT64)PteBase + ((v12 >> 9) & 0x7FFFFFFFF8i64);
--v39;
}
while( v39 );
}
v36 = ThreadContext;
}
*((_QWORD *)v36 + 4) = v12;
v36[16] = LargePageIndexa;
*((_QWORD *)v36 + 5) = v38;
*((_QWORD *)v36 + 6) = v38 + (NumberOfPtes << 12) - 1;
MiMakeProtectionPfnCompatible((_BYTE *)4, v32);
v43 = v41 | 0xA0000000;
if( LargePageIndexa <= 1 )
v43 = v41 | 0xA4000000;
LODWORD(v44) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v12, v42, v43);
v45 = v44;
if( LargePageIndexa > 1 )
{
if( v12 < v12 + 8 * NumberOfPtes )
{
v47 = v12 + 8 * NumberOfPtes;
do
{
v48 = v45;
LOBYTE(v49) = MiPteInShadowRange(v12);
if( v49 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v45 & 1) != 0 )
v48 = v45 | 0x8000000000000000ui64;
*(_QWORD *)v12 = v48;
v45 ^= (v45 ^ ((v45 & 0xFFFFFFFFFFFFF000ui64) + 4096)) & 0xFFFFFFFFF000i64;
v12 += 8i64;
}
while( v12 < v47 );
v13 = v70;
LODWORD(v10) = v77;
}
v12 -= 8 * NumberOfPtes;
}
else
{
LOBYTE(v46) = MiPteInShadowRange(v12);
if( v46 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v45 & 1) != 0 )
v45 |= 0x8000000000000000ui64;
*(_QWORD *)v12 = v45;
}
v50 = WorkPage;
p_Lock = &WorkPage->u2.Lock;
_InterlockedAnd64(&WorkPage->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v66);
v102 = --v75;
v71 = 0;
v51 = v50;
v81 = v50;
v52 = &v50[NumberOfPtes];
v80 = v52;
v53 = (_MMPFN *)Pfn1;
while( 1 )
{
v93 = v53;
if( v50 >= v52 )
{
v58 = 0;
goto LABEL_67;
}
v54 = MiScrubPage((VOID *)v86, v50, v53, 0i64);
v55 = MiLockPageInline(v51);
v67 = v55;
v56 = *((_BYTE *)ThreadContext + 69);
if( *((_BYTE *)ThreadContext + 70) == 1 )
v54 = 0;
v71 = v54;
if( v56 == 1 || v54 < 0 )
break;
v51 = v81;
_InterlockedAnd64(&v81->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v55);
v50 = ++WorkPage;
v53 = (_MMPFN *)((char *)v93 + 4096);
v52 = v80;
}
MiRemoveFaultNode(ThreadContext);
v57 = v56 == 0;
v51 = v81;
if( v57 )
MiPageListCollision(v81);
_InterlockedAnd64(&v81->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v67);
v58 = 1;
LABEL_67:
if( !v58 )
{
v59 = MiLockPageInline(v51);
MiRemoveFaultNode(ThreadContext);
if( !*((_BYTE *)ThreadContext + 69) )
MiPageListCollision(v51);
_InterlockedAnd64(p_Lock, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v59);
}
v15 = -1431655765;
v60 = WorkPage - v51;
v61 = v94;
if( v60 + v87 <= v106 )
v61 = v60 + v87;
v87 = v61;
*v88 = v61;
if( v71 < 0 )
{
StartAddress.QuadPart = (WorkPage - MmGetPfnDb()) << 12;
NumberOfBytes.QuadPart = 4096i64;
StartAddress.anonymous_0.LowPart |= 1u;
MmMarkPhysicalMemoryAsBad(&StartAddress, &NumberOfBytes);
}
if( v61 >= v107 )
goto LABEL_80;
if( LargePageIndexa > 1 )
{
v30 = NumberOfPtes;
MiReleasePtes(
(_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432),
(_MMPTE *)v12,
(unsigned int)NumberOfPtes,
(_KTBFLUSH_TYPE)v15);
v62 = (UINT64)MiReservePtes(
(_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432),
(unsigned int)NumberOfPtes);
v12 = v62;
if( !v62 )
goto LABEL_81;
Pfn1 = (__int64)((v62 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
*((_QWORD *)ThreadContext + 4) = v62;
}
v96 = v61;
CurrentIrql = v74;
}
}
else
{
v33 = v31 - MmGetPfnDb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v32->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v32->u2._bf_0 < 0 );
}
*(_QWORD *)&v99 = v33;
*((_QWORD *)&v99 + 1) = 0x100000001i64;
CurrentIrql = v74;
v100 = v74;
MiInsertLargePageInNodeList((__int64)&v99);
}
v15 = PageType;
v21 = v89;
v23 = v75;
v20 = Channel;
}
v22 = v78 + 1;
v21 = v90 + 3;
}
LABEL_80:
v30 = NumberOfPtes;
LABEL_81:
v29 = 1;
LABEL_82:
v98->SameThreadPassiveFlags &= ~0x100u;
if( PageType && LargePageIndexa > 1 )
{
if( v12 )
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), (_MMPTE *)v12, v30, (_KTBFLUSH_TYPE)v15);
}
return v29;
}Referenced by:
MiScrubNodeLargePages