MiMigratePfn
_MMPFN *__fastcall MiMigratePfn(UINT64 *a1, INT64 a2, __int64 a3, _QWORD *a4){
UINT64 p_PageColor;
_MMPFN *PfnDb;
VOID *v8;
_MMSUPPORT_INSTANCE *v9;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v10;
int v11;
struct _KPRCB *CurrentPrcb;
unsigned int NodeShiftedColor;
int v14;
unsigned int v15;
unsigned __int64 v16;
void *v17;
__int64 v18;
UINT8 v19;
wchar_t *v20;
signed __int32 v21;
_UNICODE_STRING *v22;
unsigned int v23;
unsigned int *v24;
unsigned int *v25;
__int64 v26;
__int64 v27;
int v28;
_MMPFN *v29;
_MI_PARTITION *v30;
unsigned int v31;
unsigned int v32;
int v33;
unsigned int v34;
INT64 v35;
UINT64 v36;
_MI_PARTITION *v37;
_MMPFN *v39;
__int64 v40;
__int64 v41;
unsigned int *v42;
__int64 v43;
__int64 v44;
__int64 v45;
__int64 v46;
int v47;
_MMPTE *v48;
INT64 v49;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v50;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v51;
int v52;
PVOID v53;
INT64 v54;
UINT64 v55;
unsigned __int16 ReferenceCount;
INT64 v57;
UINT64 v58;
UINT64 v59;
ULONG_PTR *Partition;
INT64 v61;
PVOID BugCheckParameter2;
__int64 v63;
UINT64 v64;
UINT64 SpinCount;
UINT64 v66;
_QWORD *v67;
v67 = a4;
p_PageColor = a1[7];
v64 = *a1;
v61 = a1[2];
if( (*(_QWORD *)(a2 + 40) & 0x2000000000000i64) != 0 )
return(_MMPFN *)a2;
PfnDb = MmGetPfnDb();
if( *(&stru_140C50B28 + 4726) )
{
if( _bittest64(*(&stru_140C50B28 + 756), (unsigned __int64)((a2 - (__int64)PfnDb) / 48) >> 9) )
return(_MMPFN *)a2;
}
if( (unsigned __int16)KeNumberNodes <= 1u
|| *(_WORD *)(a2 + 32)
|| ((__int64)KeGetCurrentThread()[1].Queue & 0x40) != 0
|| !MiCanPageMove((_MMPFN *)a2) )
{
return(_MMPFN *)a2;
}
v10.Long = 0i64;
v63 = 0i64;
MiComputeFaultNode(v9, 0i64, (_CONTROL_AREA *)&v63, v8, (_MMVAD **)v59);
if( v11 )
{
CurrentPrcb = KeGetCurrentPrcb();
NodeShiftedColor = (v11 - 1) << *(&stru_140C4DB30 + 156);
}
else
{
CurrentPrcb = *(&KiProcessorBlock + KeGetCurrentThread()->IdealProcessor);
NodeShiftedColor = CurrentPrcb->NodeShiftedColor;
}
v14 = (1 << *(&stru_140C4DB30 + 157)) - 1;
if( !p_PageColor || (*(_BYTE *)(p_PageColor + 184) & 7u) >= 2 )
p_PageColor = (UINT64)&CurrentPrcb->PageColor;
v15 = NodeShiftedColor >> *(&stru_140C4DB30 + 156);
v16 = (__int64)((unsigned __int128)((a2 - (__int64)PfnDb) * (__int128)0x2AAAAAAAAAAAAAABi64) >> 64) >> 3;
v17 = (void *)((v16 >> 63) + v16);
BugCheckParameter2 = v17;
LODWORD(v18) = MiSearchNumaNodeTable(v17);
if( v15 == *(_DWORD *)(v18 + 8) )
return(_MMPFN *)a2;
Partition = *(ULONG_PTR **)(*(&stru_140C4DB30 + 267) + 8 * ((*(_QWORD *)(a2 + 40) >> 39) & 0x3FFi64));
v21 = _InterlockedExchangeAdd((volatile signed __int32 *)p_PageColor, 1u);
v22 = (_UNICODE_STRING *)(unsigned __int16)KeNumberNodes;
v23 = v14 & v21 | NodeShiftedColor;
v24 = (unsigned int *)(*(&stru_140C4DB30 + 21) + 4i64 * v15 * (unsigned __int16)KeNumberNodes);
v25 = &v24[(unsigned __int16)KeNumberNodes];
if( v24 < v25 )
{
while( 1 )
{
LODWORD(v26) = MiSearchNumaNodeTable(v17);
v27 = *v24;
if( (_DWORD)v27 == *(_DWORD *)(v26 + 8) )
return(_MMPFN *)a2;
if( *(_OWORD *)(*((_QWORD *)Partition + 2) + 4544 * v27 + 4128) == 0i64 && ++v24 < v25 )
continue;
break;
}
}
LOBYTE(v28) = MI_PFN_IS_PROTO((_UNICODE_STRING *)a2, v22, v19, v20);
if( v28 && (*(_DWORD *)(a2 + 16) & 0x400i64) != 0 )
{
v32 = v31;
}
else
{
MiIsPfnCommitNotCharged(v29);
v32 = 0;
if( v33 )
v32 = 5;
}
if( !MiObtainFaultCharges(v30, v31, v32) )
return(_MMPFN *)a2;
v34 = 1;
if( (v61 & 1) != 0 && *(_BYTE *)(v61 & 0xFFFFFFFFFFFFFFFEui64) == 4 || MiGetSystemRegionType(v64) == 12 )
v34 = 9;
LODWORD(v35) = MiGetPage(Partition, v23, v34);
v61 = v35;
if( v35 == -1 )
{
v36 = v32;
v37 = (_MI_PARTITION *)Partition;
LABEL_31:
MiReturnFaultCharges(v37, 1ui64, v36);
return(_MMPFN *)a2;
}
v39 = &MmGetPfnDb()[v35];
v40 = 48 * v35 / 48;
LODWORD(v41) = MiSearchNumaNodeTable((PVOID)v40);
if( v15 != *(_DWORD *)(v41 + 8) )
{
v42 = (unsigned int *)(*(&stru_140C4DB30 + 21) + 4i64 * v15 * (unsigned __int16)KeNumberNodes);
if( v42 < v25 )
{
while( 1 )
{
LODWORD(v43) = MiSearchNumaNodeTable(BugCheckParameter2);
if( *v42 == *(_DWORD *)(v43 + 8) )
goto LABEL_40;
LODWORD(v44) = MiSearchNumaNodeTable((PVOID)v40);
if( *v42 != *(_DWORD *)(v44 + 8) && ++v42 < v25 )
continue;
break;
}
}
}
if( a3 )
{
MiGetInPageSupportBlock();
if( !v45 )
{
LABEL_40:
MiLockNestedPageAtDpcInline(v39);
MiReturnFreeZeroPage((INT64)v39);
_InterlockedAnd64(&v39->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v37 = (_MI_PARTITION *)Partition;
v36 = v32;
goto LABEL_31;
}
v46 = v45;
}
else
{
v46 = 0i64;
}
v47 = *(unsigned __int8 *)(a2 + 34) >> 6;
MiLockNestedPageAtDpcInline(v39);
if( *((unsigned __int8 *)&v39->u3 + 2) >> 6 != v47 )
MiChangePageAttribute(v39, (_MI_PFN_CACHE_ATTRIBUTE)v47, 1ui64);
MiSetPfnTbFlushStamp(v39, 0i64, 1ui64);
MiCopyPfnEntryEx((INT64)v39, a2);
v39->u3.ReferenceCount = 1;
v39->u2._bf_0 &= 0xC000000000000000ui64;
*(_BYTE *)(a2 + 34) = *(_BYTE *)(a2 + 34) & 0xF8 | 5;
if( v46 )
{
*(_DWORD *)(v46 + 192) |= 0x20u;
*((_BYTE *)&v39->u3 + 2) |= 0x20u;
v39->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = v46 + 32;
*(_QWORD *)(v46 + 248) = v39;
}
v48 = (_MMPTE *)(v39->PteLong | 0x8000000000000000ui64);
LODWORD(v49) = MI_READ_PTE_LOCK_FREE((INT64)v48);
LODWORD(v50.Long) = MiUpdateTransitionPteFrame(v49, v61);
v51.Long = v50.Long;
LOBYTE(v52) = MiPteInShadowRange((UINT64)v48);
if( v52 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v51.Long & 1) != 0 )
v51.Long |= 0x8000000000000000ui64;
v48->u.Long = v51.Long;
_InterlockedAnd64(&v39->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( a3 )
{
MiLockNestedPageAtDpcInline((_MMPFN *)a3);
if( !MiAreChargesNeededToLockPage((_MMPFN *)a3) || MiChargeForLockedPage((_MMPFN *)a3, 3ui64) )
++*(_WORD *)(a3 + 32);
_InterlockedAnd64((volatile signed __int64 *)(a3 + 24), 0x7FFFFFFFFFFFFFFFui64);
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(a3 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)(a3 + 24) < 0 );
}
*(_BYTE *)(a3 + 34) &= ~0x20u;
MiRemoveLockedPageChargeAndDecRef((_MMPFN *)a3);
_InterlockedAnd64((volatile signed __int64 *)(a3 + 24), 0x7FFFFFFFFFFFFFFFui64);
*v67 = v46;
}
else
{
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(2ui64);
}
v53 = BugCheckParameter2;
MiCopyPage(v61, (UINT64)BugCheckParameter2, 0i64, 2ui64);
if( a3 )
{
MiLockProtoPoolPage(v48, 0i64);
LODWORD(v66) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(a3 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx(&v66);
while( *(__int64 *)(a3 + 24) < 0 );
}
MiRemoveLockedPageChargeAndDecRef((_MMPFN *)a3);
_InterlockedAnd64((volatile signed __int64 *)(a3 + 24), 0x7FFFFFFFFFFFFFFFui64);
LODWORD(v59) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(a2 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx(&v59);
while( *(__int64 *)(a2 + 24) < 0 );
}
}
else
{
MiLockPageInline((_MMPFN *)a2);
}
*(_QWORD *)(a2 + 40) &= 0x8FFFFFFFFFFFFFFFui64;
MiInsertPageInFreeOrZeroedList((UINT64)v53, 2ui64, v54, v55, v59, (UINT64)Partition);
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
HIDWORD(v59) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v39->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v59 + 4));
while( v39->u2._bf_0 < 0 );
}
ReferenceCount = v39->u3.ReferenceCount;
*((_BYTE *)&v39->u3 + 2) &= ~0x20u;
v39->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = 0i64;
MiRemoveLockedPageCharge(v39);
if( !v46 )
return v39;
*(_DWORD *)(v46 + 192) &= ~0x20u;
if( (v39->u2._bf_0 & 0x4000000000000000i64) == 0 )
return v39;
if( ReferenceCount == 1 )
{
if( (*(_DWORD *)(&v39->3 + 1) & 0x400i64) == 0 )
v10.Long = MiCapturePageFileInfoInline(&v39->OriginalPte, 0i64, 1ui64).u.Long;
MiInsertPageInFreeOrZeroedList(v61, 2ui64, v57, v58, v59, (UINT64)Partition);
}
_InterlockedAnd64(&v39->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( a3 )
MiUnlockProtoPoolPage(a3, 2u);
if( v10.Long )
MiReleasePageFileInfo((_MI_PARTITION *)Partition, (_MMPTE)v10.Long, 1ui64);
return 0i64;
}Referenced by:
MiHandleTransitionFault