MiMigratePfn
_MMPFN *__stdcall MiMigratePfn(
_MMSUPPORT_INSTANCE *Vm,
PVOID FaultingAddress,
_MMPFN *Pfn1,
_MMPFN *LockedProtoPfn,
PVOID TrapInformation,
_MMINPAGE_SUPPORT **ReadBlock){
unsigned __int64 v6;
_MMPFN *PfnDb;
void *v10;
_MMSUPPORT_INSTANCE *v11;
UINT64 v12;
int v13;
struct _KPRCB *CurrentPrcb;
unsigned int v15;
int v16;
unsigned int v17;
unsigned __int64 v18;
void *v19;
__int64 v20;
UINT8 v21;
WCHAR *v22;
signed __int32 v23;
UNICODE_STRING *v24;
unsigned int v25;
unsigned int *v26;
unsigned int *v27;
__int64 v28;
__int64 v29;
int v30;
INT64 v31;
_MI_PARTITION *v32;
unsigned int v33;
unsigned int v34;
unsigned int v35;
ULONG_PTR Page;
UINT64 v37;
_MI_PARTITION *v38;
char *v40;
__int64 v41;
__int64 v42;
unsigned int *v43;
__int64 v44;
__int64 v45;
_DWORD *v46;
_DWORD *v47;
unsigned int v48;
_MMPTE *v49;
INT64 v50;
ULONG_PTR v51;
__int16 v52;
UINT64 v53;
INT64 v54;
UINT64 v55;
_MI_PARTITION *Partition;
ULONG_PTR PageFrameIndex;
ULONG_PTR BugCheckParameter2;
INT64 a9;
UINT64 v60;
INT64 v61;
INT64 v62;
UINT64 SpinCount;
UINT64 v64;
_MMPFN *v65;
v65 = LockedProtoPfn;
v6 = Vm->AgeDistribution[2];
v60 = *(_QWORD *)&Vm->NextPageColor;
PageFrameIndex = (ULONG_PTR)Vm->VmWorkingSetList;
if( (*((_QWORD *)FaultingAddress + 5) & 0x2000000000000i64) != 0 )
return(_MMPFN *)FaultingAddress;
PfnDb = MmGetPfnDb();
if( byte_140C51D9E )
{
if( _bittest64(
(const signed __int64 *)qword_140C522C8,
(unsigned __int64)(((_BYTE *)FaultingAddress - (_BYTE *)PfnDb) / 48) >> 9) )
{
return(_MMPFN *)FaultingAddress;
}
}
if( (unsigned __int16)KeNumberNodes <= 1u
|| *((_WORD *)FaultingAddress + 16)
|| (*((_BYTE *)KeGetCurrentThread() + 1304) & 0x40) != 0
|| !MiCanPageMove((INT64)FaultingAddress) )
{
return(_MMPFN *)FaultingAddress;
}
v12 = 0i64;
a9 = 0i64;
MiComputeFaultNode(v11, 0i64, (_CONTROL_AREA *)&a9, v10, (_MMVAD **)v55);
if( v13 )
{
CurrentPrcb = KeGetCurrentPrcb();
v15 = (v13 - 1) << byte_140C4DBCC;
}
else
{
CurrentPrcb = *(&KiProcessorBlock + *((unsigned int *)KeGetCurrentThread() + 147));
v15 = *((_DWORD *)CurrentPrcb + 8134);
}
v16 = (1 << byte_140C4DBCD) - 1;
if( !v6 || (*(_BYTE *)(v6 + 184) & 7u) >= 2 )
v6 = (unsigned __int64)CurrentPrcb + 32528;
v17 = v15 >> byte_140C4DBCC;
v18 = (__int64)((unsigned __int128)(((_BYTE *)FaultingAddress - (_BYTE *)PfnDb) * (__int128)0x2AAAAAAAAAAAAAABi64) >> 64) >> 3;
v19 = (void *)((v18 >> 63) + v18);
BugCheckParameter2 = (ULONG_PTR)v19;
LODWORD(v20) = MiSearchNumaNodeTable(v19);
if( v17 == *(_DWORD *)(v20 + 8) )
return(_MMPFN *)FaultingAddress;
Partition = *(_MI_PARTITION **)(qword_140C4E388 + 8 * ((*((_QWORD *)FaultingAddress + 5) >> 39) & 0x3FFi64));
v23 = _InterlockedExchangeAdd((volatile signed __int32 *)v6, 1u);
v24 = (UNICODE_STRING *)(unsigned __int16)KeNumberNodes;
v25 = v16 & v23 | v15;
v26 = (unsigned int *)(qword_140C4DBD8 + 4i64 * v17 * (unsigned __int16)KeNumberNodes);
v27 = &v26[(unsigned __int16)KeNumberNodes];
if( v26 < v27 )
{
while( 1 )
{
LODWORD(v28) = MiSearchNumaNodeTable(v19);
v29 = *v26;
if( (_DWORD)v29 == *(_DWORD *)(v28 + 8) )
return(_MMPFN *)FaultingAddress;
if( *(_OWORD *)(*((_QWORD *)Partition + 2) + 4544 * v29 + 4128) == 0i64 && ++v26 < v27 )
continue;
break;
}
}
LOBYTE(v30) = MI_PFN_IS_PROTO((UNICODE_STRING *)FaultingAddress, v24, v21, v22);
if( v30 && (*((_DWORD *)FaultingAddress + 4) & 0x400i64) != 0 )
{
v34 = v33;
}
else
{
v34 = 0;
if( (unsigned int)MiIsPfnCommitNotCharged(v31) )
v34 = 5;
}
if( !(unsigned int)MiObtainFaultCharges(v32, v33, v34) )
return(_MMPFN *)FaultingAddress;
v35 = 1;
if( (PageFrameIndex & 1) != 0 && *(_BYTE *)(PageFrameIndex & 0xFFFFFFFFFFFFFFFEui64) == 4
|| (unsigned int)MiGetSystemRegionType(v60) == 12 )
{
v35 = 9;
}
Page = MiGetPage(Partition, v25, v35);
PageFrameIndex = Page;
if( Page == -1i64 )
{
v37 = v34;
v38 = Partition;
LABEL_31:
MiReturnFaultCharges(v38, 1ui64, v37);
return(_MMPFN *)FaultingAddress;
}
v40 = (char *)MmGetPfnDb() + 48 * Page;
v41 = (__int64)(48 * Page) / 48;
LODWORD(v42) = MiSearchNumaNodeTable((PVOID)v41);
if( v17 != *(_DWORD *)(v42 + 8) )
{
v43 = (unsigned int *)(qword_140C4DBD8 + 4i64 * v17 * (unsigned __int16)KeNumberNodes);
if( v43 < v27 )
{
while( 1 )
{
LODWORD(v44) = MiSearchNumaNodeTable((PVOID)BugCheckParameter2);
if( *v43 == *(_DWORD *)(v44 + 8) )
goto LABEL_40;
LODWORD(v45) = MiSearchNumaNodeTable((PVOID)v41);
if( *v43 != *(_DWORD *)(v45 + 8) && ++v43 < v27 )
continue;
break;
}
}
}
if( Pfn1 )
{
v46 = MiGetInPageSupportBlock(6);
if( !v46 )
{
LABEL_40:
MiLockNestedPageAtDpcInline((INT64)v40);
MiReturnFreeZeroPage((INT64)v40);
_InterlockedAnd64((volatile signed __int64 *)v40 + 3, 0x7FFFFFFFFFFFFFFFui64);
v38 = Partition;
v37 = v34;
goto LABEL_31;
}
v47 = v46;
}
else
{
v47 = 0i64;
}
v48 = *((unsigned __int8 *)FaultingAddress + 34) >> 6;
MiLockNestedPageAtDpcInline((INT64)v40);
if( (unsigned __int8)v40[34] >> 6 != v48 )
MiChangePageAttribute((INT64)v40, v48, 1);
MiSetPfnTbFlushStamp((_MMPFN *)v40, 0i64, 1ui64);
MiCopyPfnEntryEx((INT64)v40, (INT64)FaultingAddress);
*((_WORD *)v40 + 16) = 1;
*((_QWORD *)v40 + 3) &= 0xC000000000000000ui64;
*((_BYTE *)FaultingAddress + 34) = *((_BYTE *)FaultingAddress + 34) & 0xF8 | 5;
if( v47 )
{
v47[48] |= 0x20u;
v40[34] |= 0x20u;
*(_QWORD *)v40 = v47 + 8;
*((_QWORD *)v47 + 31) = v40;
}
v49 = (_MMPTE *)(*((_QWORD *)v40 + 1) | 0x8000000000000000ui64);
v50 = MI_READ_PTE_LOCK_FREE((INT64)v49);
*(_QWORD *)v49 = MiUpdateTransitionPteFrame(v50, PageFrameIndex);
_InterlockedAnd64((volatile signed __int64 *)v40 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( Pfn1 )
{
MiLockNestedPageAtDpcInline((INT64)Pfn1);
if( !(unsigned int)MiAreChargesNeededToLockPage((INT64)Pfn1) || (unsigned int)MiChargeForLockedPage((INT64)Pfn1, 3) )
++*((_WORD *)Pfn1 + 16);
_InterlockedAnd64((volatile signed __int64 *)Pfn1 + 3, 0x7FFFFFFFFFFFFFFFui64);
_InterlockedAnd64((volatile signed __int64 *)FaultingAddress + 3, 0x7FFFFFFFFFFFFFFFui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)Pfn1 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((__int64 *)Pfn1 + 3) < 0 );
}
*((_BYTE *)Pfn1 + 34) &= ~0x20u;
MiRemoveLockedPageChargeAndDecRef(Pfn1);
_InterlockedAnd64((volatile signed __int64 *)Pfn1 + 3, 0x7FFFFFFFFFFFFFFFui64);
*(_QWORD *)v65 = v47;
}
else
{
_InterlockedAnd64((volatile signed __int64 *)FaultingAddress + 3, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(2ui64);
}
v51 = BugCheckParameter2;
MiCopyPage(PageFrameIndex, BugCheckParameter2, 0i64, 2);
if( Pfn1 )
{
MiLockProtoPoolPage(v49, 0i64);
LODWORD(v64) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)Pfn1 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v64);
while( *((__int64 *)Pfn1 + 3) < 0 );
}
MiRemoveLockedPageChargeAndDecRef(Pfn1);
_InterlockedAnd64((volatile signed __int64 *)Pfn1 + 3, 0x7FFFFFFFFFFFFFFFui64);
LODWORD(v55) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)FaultingAddress + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v55);
while( *((__int64 *)FaultingAddress + 3) < 0 );
}
}
else
{
MiLockPageInline((INT64)FaultingAddress);
}
*((_QWORD *)FaultingAddress + 5) &= 0x8FFFFFFFFFFFFFFFui64;
MiInsertPageInFreeOrZeroedList(v51, 2ui64);
_InterlockedAnd64((volatile signed __int64 *)FaultingAddress + 3, 0x7FFFFFFFFFFFFFFFui64);
HIDWORD(v55) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v40 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v55 + 4));
while( *((__int64 *)v40 + 3) < 0 );
}
v52 = *((_WORD *)v40 + 16);
v40[34] &= ~0x20u;
*(_QWORD *)v40 = 0i64;
MiRemoveLockedPageCharge((INT64)v40);
if( !v47 )
return(_MMPFN *)v40;
v47[48] &= ~0x20u;
if( (*((_QWORD *)v40 + 3) & 0x4000000000000000i64) == 0 )
return(_MMPFN *)v40;
if( v52 == 1 )
{
if( (*((_DWORD *)v40 + 4) & 0x400i64) == 0 )
v12 = MiCapturePageFileInfoInline((UINT64 *)v40 + 2, 0i64, 1i64);
MiInsertPageInFreeOrZeroedList(PageFrameIndex, 2ui64);
}
_InterlockedAnd64((volatile signed __int64 *)v40 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( Pfn1 )
{
LOBYTE(v53) = 2;
MiUnlockProtoPoolPage(Pfn1, v53);
}
if( v12 )
MiReleasePageFileInfo(
(INT64)Partition,
v12,
1,
v54,
v55,
(INT64)Partition,
PageFrameIndex,
BugCheckParameter2,
a9,
v60,
v61,
v62);
return 0i64;
}Referenced by:
MiHandleTransitionFault