MiSwapNumaStandbyPage
NTSTATUS __stdcall MiSwapNumaStandbyPage(INT64 BlinkValue, UINT64 PreferredNode, UINT64 PreferredChannel, INT8 Flags){
__int64 v4;
_MMPFN *PfnDb;
unsigned int v6;
INT64 v7;
unsigned int v8;
INT64 v9;
int v10;
__int64 v11;
char *IoObject;
PRIVILEGE_SET **v13;
_ETHREAD *WorkOnBehalfThread;
int v15;
__int64 v16;
__int64 v17;
_LIST_ENTRY *v18;
_QWORD *v19;
void(__fastcall *v20)(void *, void *, _IO_WORKITEM *);
_LIST_ENTRY *Parameter;
unsigned __int8 CurrentIrql;
ULONG_PTR v23;
char *v24;
void *v25;
__int64 v26;
ULONG_PTR v28;
unsigned __int64 v29;
volatile signed __int32 *v30;
unsigned int v31;
unsigned __int64 v32;
__int64 v33;
UINT64 v34;
INT64 v35;
unsigned __int64 *v36;
UINT64 v37;
INT64 updated;
__int64 v39;
__int64 v40;
_MMPFN *v41;
_MMPFN *v42;
_LIST_ENTRY *v43;
_MMPFN *v44;
CHAR v45;
__int64 v46;
__int64 v47;
unsigned __int64 v48;
INT64 v49;
__int64 v50;
__int64 v51;
__int64 v52;
INT64 *v53;
__int64 v54;
INT64 v55;
WORK_QUEUE_TYPE v56;
void *v57;
unsigned int v58;
char v59;
char v60;
signed __int32 v61[8];
UINT64 v62;
_LIST_ENTRY *v63;
PRIVILEGE_SET **v64;
INT64 *v65;
_QWORD *v66;
struct _IO_WORKITEM LockHandle;
int v69;
v4 = (unsigned int)PreferredNode;
PfnDb = MmGetPfnDb();
memset(&LockHandle, 0, 24);
v6 = PreferredChannel;
v7 = BlinkValue;
v8 = MmNumberOfChannels;
v9 = (INT64)PfnDb + 48 * BlinkValue;
v10 = 0;
v69 = 0;
v11 = (*(_QWORD *)(v9 + 40) >> 39) & 0x3FFi64;
LODWORD(v62) = 0;
HIDWORD(v62) = MmNumberOfChannels;
IoObject = *(char **)(qword_140C4E388 + 8 * v11);
v13 = 0i64;
LockHandle.IoObject = IoObject;
v64 = 0i64;
WorkOnBehalfThread = (_ETHREAD *)(*((_QWORD *)IoObject + 2) + 4544 * v4);
LockHandle.WorkOnBehalfThread = WorkOnBehalfThread;
v15 = *((_DWORD *)WorkOnBehalfThread + 1070) & 1;
LODWORD(v65) = v15;
if( (unsigned int)MmNumberOfChannels > 1 )
{
v13 = (PRIVILEGE_SET **)((char *)WorkOnBehalfThread + 4313);
v64 = (PRIVILEGE_SET **)((char *)WorkOnBehalfThread + 4313);
if( v15 )
{
if( (Flags & 0x20) != 0 )
{
v8 = 1;
v69 = v6;
v13 = 0i64;
HIDWORD(v62) = 1;
v64 = 0i64;
goto LABEL_10;
}
if( (Flags & 8) != 0 )
{
v13 = (PRIVILEGE_SET **)((char *)WorkOnBehalfThread + 4317);
v64 = (PRIVILEGE_SET **)((char *)WorkOnBehalfThread + 4317);
}
}
else
{
LODWORD(v16) = MiSearchNumaNodeTable((PVOID)((v9 - (__int64)PfnDb) / 48));
if( *(_DWORD *)(v16 + 8) == (_DWORD)v4 )
return v7;
v13 = v64;
v10 = v6;
v8 = HIDWORD(v62);
v15 = (int)v65;
IoObject = (char *)LockHandle.IoObject;
LODWORD(v62) = v6;
}
}
v6 = 0;
LABEL_10:
*(_QWORD *)&LockHandle.Type = (char *)v13 + v8;
while( 1 )
{
if( v13 )
{
if( v15 )
{
v6 = *(unsigned __int8 *)v13;
v69 = v6;
LODWORD(v17) = MiSearchNumaNodeTable((PVOID)((v9 - (__int64)MmGetPfnDb()) / 48));
if( *(_DWORD *)(v17 + 8) == (_DWORD)v4 && v6 == (unsigned int)MiGetPfnChannel(v9) )
return v7;
IoObject = (char *)LockHandle.IoObject;
}
else
{
v69 = v10;
v6 = v10;
v10 = v10 + 1 < v8 ? v10 + 1 : 0;
LODWORD(v62) = v10;
}
}
LockHandle.WorkItem.Parameter = IoObject + 2752;
v18 = (_LIST_ENTRY *)(IoObject + 2432);
v63 = (_LIST_ENTRY *)(IoObject + 2432);
if( IoObject + 2432 < IoObject + 2752 )
break;
LABEL_33:
v13 = (PRIVILEGE_SET **)((char *)v64 + 1);
v64 = v13;
if( (unsigned __int64)v13 >= *(_QWORD *)&LockHandle.Type )
return v7;
v8 = HIDWORD(v62);
v15 = (int)v65;
}
v19 = (_QWORD *)((char *)WorkOnBehalfThread + 192 * v6 + 3264);
v20 = (void(__fastcall *)(void *, void *, _IO_WORKITEM *))(IoObject + 2464);
v66 = v19;
Parameter = (_LIST_ENTRY *)(IoObject + 2752);
LockHandle.Routine = (void(__fastcall *)(void *, void *, _IO_WORKITEM *))(IoObject + 2464);
while( *v19 == 0xFFFFFFFFFi64 )
{
LABEL_31:
v18 = (_LIST_ENTRY *)((char *)v18 + 40);
v20 = (void(__fastcall *)(void *, void *, _IO_WORKITEM *))((char *)v20 + 40);
v19 += 3;
v63 = v18;
LockHandle.Routine = v20;
v66 = v19;
if( v18 >= Parameter )
{
v10 = v62;
WorkOnBehalfThread = LockHandle.WorkOnBehalfThread;
v6 = v69;
IoObject = (char *)LockHandle.IoObject;
goto LABEL_33;
}
}
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
LockHandle.WorkItem.List.Flink = 0i64;
LockHandle.WorkItem.List.Blink = (_LIST_ENTRY *)v20;
KxAcquireQueuedSpinLock(&LockHandle, (PIO_WORKITEM_ROUTINE)v20, (WORK_QUEUE_TYPE)v15, (PVOID)0xFFFFFFFFFi64);
v23 = *v19;
if( v23 == 0xFFFFFFFFFi64 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
__writecr8(CurrentIrql);
v19 = v66;
v18 = v63;
LABEL_30:
Parameter = (_LIST_ENTRY *)LockHandle.WorkItem.Parameter;
goto LABEL_31;
}
v24 = (char *)MmGetPfnDb() + 48 * v23;
if( !_interlockedbittestandset64((volatile signed __int32 *)v24 + 6, 0x3Fui64) )
goto LABEL_35;
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
LODWORD(LockHandle.Context) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v24 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)&LockHandle.Context);
while( *((__int64 *)v24 + 3) < 0 );
}
if( (v24[34] & 7) != 2 )
{
LABEL_29:
_InterlockedAnd64((volatile signed __int64 *)v24 + 3, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(CurrentIrql);
v18 = (_LIST_ENTRY *)((char *)v63 - 40);
v20 = (void(__fastcall *)(void *, void *, _IO_WORKITEM *))((char *)LockHandle.Routine - 40);
v19 = v66 - 3;
goto LABEL_30;
}
LockHandle.WorkItem.List.Flink = 0i64;
LockHandle.WorkItem.List.Blink = (_LIST_ENTRY *)LockHandle.Routine;
KxAcquireQueuedSpinLock(&LockHandle, (PIO_WORKITEM_ROUTINE)LockHandle.Routine, (WORK_QUEUE_TYPE)v15, v25);
if( v23 != *v66 )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
goto LABEL_29;
}
LABEL_35:
if( _interlockedbittestandset64((volatile signed __int32 *)(v9 + 24), 0x3Fui64) )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
_InterlockedAnd64((volatile signed __int64 *)v24 + 3, 0x7FFFFFFFFFFFFFFFui64);
goto LABEL_39;
}
if( MiCanPageMove((INT64)v24) )
{
if( dword_140C4E40C != 1 )
goto LABEL_51;
v28 = v23 & 0x1F;
LOBYTE(v29) = 1;
v30 = (volatile signed __int32 *)(qword_140C4E468 + 4 * (v23 >> 5));
if( v28 + 1 > 0x20 )
{
if( (v23 & 0x1F) != 0 )
{
_InterlockedOr(v30++, ((1 << (32 - (v23 & 0x1F))) - 1) << v28);
v29 = 1i64 - (32 - (unsigned int)(v23 & 0x1F));
if( v29 >= 0x20 )
{
v32 = v29 >> 5;
v29 += -32i64 * (v29 >> 5);
do
{
*v30++ = -1;
--v32;
}
while( v32 );
}
if( !v29 )
{
LABEL_51:
v33 = v26 & *(_QWORD *)v24;
v34 = v26 & *((_QWORD *)v24 + 3);
v35 = v26 & v7;
if( (v24[35] & 8) != 0 )
{
if( (unsigned int)MiIsDecayPfn(v34) )
{
updated = MiUpdateTransitionPteFrame(v36[2], v7);
*(_QWORD *)(v39 + 16) = updated;
}
else
{
*v36 = v35 | *v36 & 0xFFFFFFF000000000ui64;
}
if( (unsigned int)MiIsDecayPfn(v37) )
{
*(_QWORD *)(v40 + 40) = v35 | *(_QWORD *)(v40 + 40) & 0xFFFFFFF000000000ui64;
LABEL_65:
MiUnlinkNumaStandbyPage((_MMPFN *)v24);
MiFinalizePageAttribute((_MMPFN *)v9, (_MI_PFN_CACHE_ATTRIBUTE)((unsigned __int8)v24[34] >> 6), 1ui64);
MiCopyPfnEntryEx(v9, (INT64)v24);
MiInsertNumaStandbyPage(v44);
_InterlockedOr(v61, 0);
if( (((unsigned __int8)KiTbFlushTimeStamp ^ *(_BYTE *)(v9 + 31)) & 0xF) != 0 )
MiSetPfnTbFlushStamp((_MMPFN *)v9, (unsigned int)KiTbFlushTimeStamp, 1ui64);
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
v46 = *((_QWORD *)v24 + 5) & 0xFFFFFFFFFi64;
if( v46 == v23 )
{
v47 = *((_QWORD *)v24 + 1);
v48 = v35 | *(_QWORD *)(v9 + 40) & 0xFFFFFFF000000000ui64;
v49 = BlinkValue;
*(_QWORD *)(v9 + 40) = v48;
LODWORD(v50) = KeMakeKernelDirectoryTableBase(
(UINT64 *)(BlinkValue << 12),
v47,
0x8000000000000000ui64,
v45,
v62,
(INT64)v63,
v64,
v65,
(CHAR)v66,
(UINT64 *)LockHandle.WorkItem.List.Flink,
(INT64 *)LockHandle.WorkItem.List.Blink,
(CHAR)LockHandle.WorkItem.WorkerRoutine);
*(_QWORD *)((v52 | v51) - 1392) = v50;
v53 = (INT64 *)(v52 | *((_QWORD *)v24 + 1));
}
else
{
LODWORD(v54) = MiMapPageInHyperSpaceWorker(*((_QWORD *)v24 + 5) & 0xFFFFFFFFFi64, 0i64, 0x80000000ui64);
v49 = BlinkValue;
v53 = (INT64 *)(v54 + 8i64 * ((*((_DWORD *)v24 + 2) >> 3) & 0x1FF));
}
v55 = MI_READ_PTE_LOCK_FREE((INT64)v53);
*v53 = MiUpdateTransitionPteFrame(v55, v49);
if( v46 != v23 )
MiUnmapPageInHyperSpaceWorker(v53, 0x11u, 0x80000000ui64);
MiCopyPage(BlinkValue, v23, 0i64, 6);
_InterlockedOr(v61, 0);
v58 = KiTbFlushTimeStamp;
if( (((unsigned __int8)KiTbFlushTimeStamp ^ *(_BYTE *)(v9 + 31)) & 0xF) != 0 )
{
LockHandle.WorkItem.List.Flink = 0i64;
LockHandle.WorkItem.List.Blink = v63 + 2;
KxAcquireQueuedSpinLock(&LockHandle, (PIO_WORKITEM_ROUTINE)&v63[2], v56, v57);
MiSetPfnTbFlushStamp((_MMPFN *)v9, v58, 1ui64);
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
}
_InterlockedAnd64((volatile signed __int64 *)(v9 + 24), 0x7FFFFFFFFFFFFFFFui64);
v59 = v24[34];
*((_QWORD *)v24 + 5) &= ~0x8000000000000000ui64;
v24[34] = v59 & 0xC7;
v24[35] &= ~0x20u;
_InterlockedOr(v61, 0);
MiSetPfnTbFlushStamp((_MMPFN *)v24, (unsigned int)KiTbFlushTimeStamp, 1ui64);
*(_QWORD *)v24 = 0i64;
MiSetPfnBlink((_MMPFN *)v24, 0i64, 1ui64);
v24[34] = v24[34] & 0xF8 | 5;
*((_QWORD *)v24 + 2) = ZeroPte;
MiSetOriginalPtePfnFromFreeList((UINT64 *)v24 + 2);
v60 = v24[35];
*((_QWORD *)v24 + 5) &= 0x8FFFFFFFFFFFFFFFui64;
v24[35] = v60 & 0xF7;
v24[35] &= 0xF8u;
_InterlockedAnd64((volatile signed __int64 *)v24 + 3, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(CurrentIrql);
return v23;
}
v41 = (_MMPFN *)v40;
}
else
{
v42 = MmGetPfnDb();
if( v34 == v26 )
{
v43 = v63;
v63[1].Flink = (_LIST_ENTRY *)v7;
}
else
{
*((_QWORD *)v42 + 6 * v34) = v35 | *((_QWORD *)v42 + 6 * v34) & 0xFFFFFFF000000000ui64;
v43 = v63;
}
if( v33 == v26 )
{
v43[1].Blink = (_LIST_ENTRY *)v7;
goto LABEL_65;
}
v41 = (_MMPFN *)((char *)v42 + 48 * v33);
}
MiSetPfnBlink(v41, v7, 0i64);
goto LABEL_65;
}
}
v31 = (1 << v29) - 1;
}
else
{
v31 = 1 << v28;
}
_InterlockedOr(v30, v31);
goto LABEL_51;
}
_InterlockedAnd64((volatile signed __int64 *)(v9 + 24), 0x7FFFFFFFFFFFFFFFui64);
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
MiReuseStandbyPage((UINT64)v24);
*(_QWORD *)v24 = 0i64;
_InterlockedAnd64((volatile signed __int64 *)v24 + 3, 0x7FFFFFFFFFFFFFFFui64);
MiReleaseFreshPage((_MMPFN *)v9);
LODWORD(v7) = v23;
LABEL_39:
__writecr8(CurrentIrql);
return v7;
}Referenced by:
MiGetPage
MiPruneStandbyPages