MiAgePte
NTSTATUS __stdcall MiAgePte(INT64 a1, INT64 a2, UINT8 *a3){
INT64 a5;
INT64 v4;
_MMSUPPORT_INSTANCE *v5;
INT64 v6;
_MMWSL_INSTANCE *VmWorkingSetList;
unsigned __int64 WorkingSetSize;
unsigned __int64 LockedEntries;
int v10;
unsigned __int64 v11;
unsigned __int64 v12;
__int64 v13;
unsigned __int64 *v14;
char v15;
__int64 LastAccessClearingRemainder;
unsigned __int64 v17;
_KSPIN_LOCK_QUEUE *volatile Next;
unsigned __int64 v19;
_MMPTE *PteBase;
__int64 v21;
unsigned __int64 v22;
UINT64 v23;
UINT64 v24;
_MMPFN *v25;
__int64 v26;
_MMPTE *v27;
unsigned __int64 v28;
_MMPTE *PteLimit;
__int64 Blink;
UINT64 v31;
UINT64 *v32;
int v34;
INT64 a6;
_KSPIN_LOCK_QUEUE LockQueue;
__int64 v37;
int v40;
UINT64 v41;
v40 = (int)a3;
a5 = *(_QWORD *)(a1 + 168);
v4 = a2;
v5 = *(_MMSUPPORT_INSTANCE **)(a1 + 24);
v6 = a1;
VmWorkingSetList = v5->VmWorkingSetList;
if( *(_BYTE *)(a5 + 6) != 1 )
goto LABEL_22;
*(_BYTE *)(a5 + 6) = 0;
VmWorkingSetList = v5->VmWorkingSetList;
WorkingSetSize = v5->WorkingSetSize;
LockedEntries = VmWorkingSetList->LockedEntries;
if( WorkingSetSize <= LockedEntries )
return 3;
v10 = *(_DWORD *)a5;
v11 = WorkingSetSize - LockedEntries;
v12 = *(unsigned int *)(a5 + 12);
v13 = 0i64;
if( (*(_DWORD *)a5 & 4) == 0 )
{
v14 = (unsigned __int64 *)((char *)&stru_140C4DB30 + 6608);
v15 = v5->Flags._bf_0 & 7;
v37 = 0i64;
if( v15 != 2 )
v14 = &v5[1].AgeDistribution[3];
LockQueue.Lock = v14;
LockQueue.Next = 0i64;
if( _InterlockedExchange64((volatile __int64 *)v14, (__int64)&LockQueue) )
KxWaitForLockOwnerShip((INT64)&LockQueue);
if( (v10 & 2) != 0 )
{
LastAccessClearingRemainder = VmWorkingSetList->LastAccessClearingRemainder;
v17 = LastAccessClearingRemainder + v11;
VmWorkingSetList->LastAccessClearingRemainder = (LastAccessClearingRemainder + v11) % v12;
}
else
{
LastAccessClearingRemainder = VmWorkingSetList->LastAgingRemainder;
v17 = LastAccessClearingRemainder + v11;
VmWorkingSetList->LastAgingRemainder = (LastAccessClearingRemainder + v11) % v12;
}
_m_prefetchw(&LockQueue);
Next = LockQueue.Next;
if( !LockQueue.Next )
{
if( (_KSPIN_LOCK_QUEUE *)_InterlockedCompareExchange64(
(volatile signed __int64 *)LockQueue.Lock,
0i64,
(signed __int64)&LockQueue) == &LockQueue )
{
LABEL_15:
if( v17 < v11 )
LastAccessClearingRemainder = 0i64;
v13 = LastAccessClearingRemainder;
goto LABEL_18;
}
Next = KxWaitForLockChainValid(&LockQueue);
}
LockQueue.Next = 0i64;
_InterlockedXor64((volatile signed __int64 *)&Next->Lock, 1ui64);
goto LABEL_15;
}
LABEL_18:
v19 = v12 * (v13 + v11) / 0x3E8;
if( v19 > v11 )
v19 = v11 * v12 / 0x3E8;
*(_QWORD *)(a5 + 48) = v19;
if( *(_QWORD *)(a5 + 40) >= v19 )
return 3;
v4 = a2;
v6 = a1;
LABEL_22:
PteBase = MmGetPteBase();
v21 = (_QWORD)PteBase << 25;
v22 = ((v4 << 25) - ((_QWORD)PteBase << 25)) >> 16;
v23 = (UINT64)PteBase + ((v22 >> 9) & 0x7FFFFFFFF8i64);
v41 = *(_QWORD *)v23;
v24 = v41;
MiPteInShadowRange((UINT64)&v41);
v25 = &MmGetPfnDb()[(v24 >> 12) & 0xFFFFFFFFFi64];
if( v40 )
{
v27 = MmGetPteBase();
v26 = (__int64)((v23 << 25) - v21 + 0x10000000) >> 16;
v28 = ((v26 << 25) - v21) >> 16;
if( v28 >= (unsigned __int64)v27 )
{
PteLimit = MmGetPteLimit();
do
{
if( v28 > (unsigned __int64)PteLimit )
break;
v26 = v28;
v28 = (__int64)((v28 << 25) - v21) >> 16;
}
while( v28 >= (unsigned __int64)v27 );
}
}
else
{
v26 = v23 + 8;
}
if( (*(_DWORD *)a5 & 2) != 0 )
{
VmWorkingSetList->NextPteToAccessClear = (_MMPTE *)v26;
}
else if( (*(_DWORD *)a5 & 4) == 0 )
{
VmWorkingSetList->NextPteToAge = (_MMPTE *)v26;
}
if( !v40 || (v25->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) == 1 && !(unsigned int)MiIsPageTableLocked((INT64)v5, v23) )
{
if( (v25->u4._bf_0 & 0x1000000000i64) == 0 )
{
Blink = (__int64)v25->ListEntry.Blink;
if( Blink > 0 && MiDemoteCombinedPte(v5, (_MMPTE *)v23, (_MMPTE *)(Blink | 0x8000000000000000ui64)) == 1 )
{
LODWORD(v31) = MI_READ_PTE_LOCK_FREE(v23);
v41 = v31;
}
}
if( ((v41 >> 5) & 1) != 0 && (v32 = *(UINT64 **)(a5 + 248)) != 0i64 && v22 <= 0x7FFFFFFEFFFFi64 )
{
if( MiInsertVmAccessedEntry(v32, v22) )
return MiAgeWorkingSetTail(v6);
}
else
{
v34 = (v41 >> 5) & 1 | 2;
if( (*(_DWORD *)a5 & 3) == 0 )
v34 = (v41 >> 5) & 1;
LODWORD(a6) = v34;
MiAgePteWorker(v5, (_MMPTE *)v23, (VOID *)v22, v25, a5, a6);
}
if( ++*(_QWORD *)(a5 + 40) >= *(_QWORD *)(a5 + 48) )
return 3;
}
return 0;
}Referenced by:
No references.