MiRebuildLargePage
NTSTATUS __stdcall MiRebuildLargePage(_MI_PARTITION *Partition, UINT64 NodeNumber){
unsigned int v2;
unsigned __int64 v3;
__int64 v4;
unsigned __int64 v5;
__int64 v7;
unsigned __int8 *ChannelOrdering;
__int64 v9;
PHYSICAL_MEMORY_DESCRIPTOR *v10;
UINT64 v11;
UINT64 v12;
PHYSICAL_MEMORY_DESCRIPTOR *PhysicalMemoryBlock;
unsigned int v14;
_MI_NODE_INFORMATION *v15;
UINT64 v16;
UINT64 v17;
int v18;
_MMPFN *v19;
unsigned __int8 CurrentIrql;
UINT64 inserted;
struct _KPRCB *CurrentPrcb;
__int64 CachedResidentAvailable;
bool v24;
signed __int32 v25;
unsigned int v26;
unsigned __int64 v27;
unsigned int v28;
__int64 v29;
__int64 v30;
__int64 v31;
__int64 *v32;
_MI_FREE_LARGE_PAGES *v33;
__int64 v34;
unsigned __int64 v35;
__int64 v36;
UINT64 i;
__int64 v38;
int v39;
UINT64 HighestPhysicalPage;
UINT64 PreferredNode;
UINT64 Flags;
UINT64 *StartingPfn;
UINT64 NumberOfPages;
unsigned __int64 v46;
PHYSICAL_MEMORY_DESCRIPTOR *v47;
int v48;
_MI_NODE_INFORMATION *NodeInformation;
UINT64 v50;
__int128 v51;
__int64 v52;
_ETHREAD *CurrentThread;
unsigned __int8 *v54;
unsigned int v55;
unsigned int v56;
unsigned int v57;
unsigned __int64 v58;
v58 = v3;
v57 = v2;
v4 = (unsigned int)NodeNumber;
v5 = 0i64;
v52 = 0i64;
v7 = (unsigned int)MmNumberOfChannels;
ChannelOrdering = 0i64;
v55 = MmNumberOfChannels;
v9 = v2;
v48 = NodeNumber;
v51 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v46 = 0i64;
v10 = MiReferencePageRuns((ULONG_PTR *)&Partition->Core.PartitionId, 1ui64);
v11 = *(&stru_140C50B28 + 852);
v12 = MiLargePageSizes[v9];
PhysicalMemoryBlock = v10;
v14 = 0;
v47 = v10;
v15 = &Partition->Core.NodeInformation[v4];
NodeInformation = v15;
v50 = *(&stru_140C50B28 + 852);
v56 = 0;
if( (unsigned int)v7 > 1 )
{
ChannelOrdering = v15->ChannelOrdering;
v14 = v15->ChannelOrdering[0];
v56 = v14;
}
v54 = &ChannelOrdering[v7];
if( ChannelOrdering != &ChannelOrdering[v7] )
{
while( (CurrentThread->CrossThreadFlags & 1) == 0 )
{
LODWORD(v16) = MiFindRebuildCandidate(Partition, (unsigned int)v4, v14, v12, v11, PhysicalMemoryBlock);
NumberOfPages = v16;
v17 = v16;
if( v16 == -1i64 )
goto LABEL_44;
v18 = 1082130432;
if( v12 == 512 )
{
v18 = 1115684864;
}
else if( v12 == 16 )
{
v18 = 1098907648;
}
LODWORD(StartingPfn) = v18;
LODWORD(Flags) = v56;
LODWORD(PreferredNode) = v4;
if( MiFindContiguousPages(Partition, v17, v17 + v12 - 1, v12, v12, MiCached, PreferredNode, Flags, StartingPfn) >= 0 )
{
if( v12 >= 0x200 )
{
LODWORD(HighestPhysicalPage) = 1;
MiUpdateLargePageBitMap((UINT64)Partition, NumberOfPages, v12, 0i64, HighestPhysicalPage);
}
MiConvertSmallPageRangeToLarge(NumberOfPages, v57);
v19 = &MmGetPfnDb()[NumberOfPages];
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
MiLockPageAtDpc((INT64)v19);
*(_QWORD *)&v51 = NumberOfPages;
*((_QWORD *)&v51 + 1) = 1i64;
v52 = 2i64;
inserted = MiInsertLargePageInNodeList((__int64)&v51);
__writecr8(CurrentIrql);
MiReturnCommit(Partition, inserted);
if( Partition == &Irp )
{
CurrentPrcb = KeGetCurrentPrcb();
CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable;
if( (_DWORD)CachedResidentAvailable != -1 )
{
do
{
if( inserted + CachedResidentAvailable > 0x100 || inserted >= 0x80000 )
break;
v25 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
inserted + CachedResidentAvailable,
CachedResidentAvailable);
v24 = (_DWORD)CachedResidentAvailable == v25;
CachedResidentAvailable = v25;
if( v24 )
goto LABEL_26;
}
while( v25 != -1 );
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
inserted += (int)CachedResidentAvailable - 192;
}
}
}
if( inserted )
_InterlockedExchangeAdd64((volatile signed __int64 *)&Partition->Vp.ResidentAvailablePages, inserted);
LABEL_26:
v5 += v12;
v46 = v5;
if( v5 >= v58 )
{
LABEL_39:
PhysicalMemoryBlock = v47;
break;
}
}
v26 = MmNumberOfChannels;
v27 = 0i64;
v28 = 0;
if( MmNumberOfChannels )
{
do
{
LODWORD(v29) = MiNodeFreeZeroPages(NodeInformation, v28, 0i64);
v27 += v29;
++v28;
}
while( v28 < v26 );
LODWORD(v4) = v48;
}
if( v12 > 0x10 )
{
v30 = 0i64;
v31 = v57 + 1;
if( (unsigned int)v31 <= 2 )
{
v32 = &MiLargePageSizes[v31];
v33 = &NodeInformation->FreeLargePages[(unsigned int)v31];
v34 = (unsigned int)(3 - v31);
do
{
v35 = v33->LargePageFreeCount[0] + v33->LargePageFreeCount[1];
++v33;
v36 = *v32++ * v35;
v30 += v36;
--v34;
}
while( v34 );
}
v27 += v30;
}
LODWORD(v7) = v55;
if( v27 >= 0x1000 )
{
v5 = v46;
}
else
{
for( i = 0i64; (unsigned int)i < v55; i = (unsigned int)(v39 + 1) )
{
MiGetNodeStandbyPageCount(Partition, (unsigned int)v4, i);
v27 += v38;
}
v5 = v46;
if( v27 < v58 - v46 + 0x8000 )
goto LABEL_39;
}
if( !NumberOfPages )
{
LABEL_44:
++ChannelOrdering;
if( (unsigned int)v7 <= 1 )
{
v14 = v56;
}
else
{
v14 = *ChannelOrdering;
v56 = v14;
}
PhysicalMemoryBlock = v47;
v11 = v50;
if( ChannelOrdering == v54 )
break;
}
else
{
v14 = v56;
v11 = NumberOfPages - 1;
PhysicalMemoryBlock = v47;
v50 = NumberOfPages - 1;
}
}
}
MiDereferencePageRunsEx((INT64)PhysicalMemoryBlock, 1i64);
return v5;
}Referenced by:
MiRebuildLargePages
MmBuildLargePages
MmManagePartitionCreateLargePages