MiSwapStackPage
__int64 __fastcall MiSwapStackPage(__int64 a1, __int64 a2, unsigned int *a3, int a4, int a5, __int64 *a6, _DWORD *a7){
_QWORD *v10;
_QWORD *v11;
unsigned __int64 v12;
__int64 v13;
int SystemRegionType;
INT64 v15;
CHAR *AnyMultiplexedVm;
INT64 v17;
unsigned int v18;
__int128 v19;
__int64 v20;
unsigned int v21;
__int64 v22;
int v23;
INT64 Page;
char *v25;
UINT8 v26;
int v27;
int v28;
char *v29;
__int64 v30;
_KTHREAD *LeafPfnBuddy;
UINT64 *PteFromCopyList;
char v33;
__int64 v34;
_ETHREAD *v35;
_ETHREAD *v36;
int v37;
INT64 v38;
unsigned __int64 v39;
unsigned __int64 v40;
UINT8 v42;
char SpinCount[12];
INT64 v44;
PVOID Token;
_ETHREAD *CurrentThread;
__int64 v47;
Token = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
LODWORD(v10) = MiAllocatePool((struct _SLIST_ENTRY *)0x40);
v11 = v10;
if( !v10 )
return 0i64;
v10[4] = a1;
v12 = *(_QWORD *)(a2 + 8) | 0x8000000000000000ui64;
v13 = (__int64)((v12 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
v10[6] = v13;
SystemRegionType = MiGetSystemRegionType(v13);
*(_DWORD *)&SpinCount[4] = SystemRegionType;
if( SystemRegionType == 14 )
{
v15 = 4i64;
}
else
{
if( SystemRegionType != 12 )
{
LABEL_47:
ExFreePoolWithTag(v11, 0);
return 0i64;
}
v15 = 1i64;
}
AnyMultiplexedVm = MiGetAnyMultiplexedVm(v15);
v11[8] = AnyMultiplexedVm;
v17 = (INT64)AnyMultiplexedVm;
if( !byte_140C4EC1C )
goto LABEL_47;
v18 = 512;
v19 = (a2 - (__int64)MmGetPfnDb()) * (__int128)0x2AAAAAAAAAAAAAABi64;
v20 = (a2 - (__int64)MmGetPfnDb()) / 48;
v47 = v20;
if( a4 == -1 )
{
LODWORD(v22) = MiSearchNumaNodeTable((PVOID)((*((_QWORD *)&v19 + 1) >> 63) + (*((__int64 *)&v19 + 1) >> 3)));
v23 = *(_DWORD *)(v22 + 8);
v21 = ((unsigned int)MiGetPfnChannel(a2) << byte_140C4DBCD) | dword_140C4DC38 & v20 | (v23 << byte_140C4DBCC);
if( (a5 & 0x3000000) != 0 )
v18 = 66048;
}
else
{
v18 = 560;
v21 = dword_140C4DC38 & v20 | a4 & ~dword_140C4DC38;
}
Page = MiGetPage((_MI_PARTITION *)a1, v21, v18);
v44 = Page;
if( Page == -1 )
goto LABEL_47;
v25 = (char *)MmGetPfnDb() + 48 * Page;
MiSetPfnTbFlushStamp((_MMPFN *)v25, 0i64, 0i64);
v11[7] = 0i64;
*(_DWORD *)SpinCount = 0;
v26 = MiLockWorkingSetShared(v17);
v42 = v26;
while( _interlockedbittestandset64((volatile signed __int32 *)(a2 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)SpinCount);
while( *(__int64 *)(a2 + 24) < 0 );
}
if( *(_QWORD *)(qword_140C4E388 + 8 * ((*(_QWORD *)(a2 + 40) >> 39) & 0x3FFi64)) != a1
|| v12 != (*(_QWORD *)(a2 + 8) | 0x8000000000000000ui64)
|| (v27 = MiGetSystemRegionType(v11[6]), *(_DWORD *)&SpinCount[4] != v27)
|| (MiCanStealKernelStack((_MMPFN *)a2, 1u), !v28)
|| (v29 = (char *)MmGetPteBase() + ((v12 >> 9) & 0x7FFFFFFFF8i64),
!(unsigned int)MiLockPageTableInternal(v17, (UINT64)v29, (UINT8 *)1)) )
{
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
goto LABEL_45;
}
if( (MiFlags & 0x800) != 0 || (unsigned int)MiSwapStackPageNoDpc((__int64)a3, a2, (__int64)v25) != 1 )
{
LeafPfnBuddy = (_ETHREAD *)MiGetLeafPfnBuddy((_QWORD *)a2);
*(_QWORD *)&SpinCount[4] = LeafPfnBuddy;
if( (((unsigned __int64)LeafPfnBuddy + 32) & 0xFFFFFFFFFFFFFFDFui64) != 0 )
{
PteFromCopyList = MiGetPteFromCopyList((UINT64 *)a3, v44, -1i64);
if( LeafPfnBuddy != (_ETHREAD *)-16i64 && LeafPfnBuddy != CurrentThread )
{
if( KeTryToFreezeThreadStack((_KTHREAD *)LeafPfnBuddy, &Token) == 1 )
{
MiCopyKstack((INT64)v25, a2, (INT64)PteFromCopyList);
MiLockNestedPageAtDpcInline((INT64)v25);
MiSwitchKstackPages((INT64)v25, a2);
_InterlockedAnd64((volatile signed __int64 *)v25 + 3, 0x7FFFFFFFFFFFFFFFui64);
v33 = *(_BYTE *)(a2 + 34);
*(_QWORD *)(a2 + 40) &= ~0x8000000000000000ui64;
*(_BYTE *)(a2 + 34) = v33 & 0xC7;
*(_BYTE *)(a2 + 35) &= ~0x20u;
*(_QWORD *)(a2 + 24) &= 0xC000000000000000ui64;
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
KeFlushSingleTb(v11[6], 0i64, 2i64);
KiReleaseThreadStateLock(v34, (__int64)Token, 0i64);
KiReleaseThreadLockSafe(*(INT64 *)&SpinCount[4]);
*PteFromCopyList = ZeroPte;
MiUnlockPageTableInternal(v17, (UINT64)v29);
MiUnlockWorkingSetShared(v17, v42);
v30 = v44;
*a7 = 1;
goto LABEL_40;
}
goto LABEL_31;
}
if( (unsigned int)MiAddLockedPageCharge(a2, 0) )
{
v11[7] = a2;
LABEL_31:
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal(v17, (UINT64)v29);
MiUnlockWorkingSetShared(v17, v42);
v35 = CurrentThread;
v30 = v44;
*v11 = v47;
v36 = *(_ETHREAD **)&SpinCount[4];
v11[3] = v35;
v11[1] = v30;
v11[2] = PteFromCopyList;
*((_DWORD *)v11 + 10) = 0;
if( v36 == (_ETHREAD *)-16i64 || v36 == v35 )
{
v37 = KeExpandKernelStackAndCalloutInternal(MiJumpStack, v11, 24576i64);
if( v37 < 0 )
*((_DWORD *)v11 + 10) = v37;
}
else
{
KeGenericCallDpc(MiDoStackCopy, v11);
}
if( *((int *)v11 + 10) >= 0 )
{
*a7 = 0;
v40 = (unsigned __int8)MiLockPageInline(a2);
*(_QWORD *)(a2 + 24) &= 0xC000000000000000ui64;
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v40);
goto LABEL_40;
}
*PteFromCopyList = ZeroPte;
MiReleaseFreshPage((_MMPFN *)v25);
v38 = v11[7];
if( v38 )
{
v39 = (unsigned __int8)MiLockPageInline(v38);
MiRemoveLockedPageChargeAndDecRef((_MMPFN *)v11[7]);
_InterlockedAnd64((volatile signed __int64 *)(v11[7] + 24i64), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v39);
}
goto LABEL_47;
}
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal(v17, (UINT64)v29);
MiUnlockWorkingSetShared(v17, v42);
*PteFromCopyList = ZeroPte;
goto LABEL_46;
}
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal(v17, (UINT64)v29);
LABEL_45:
MiUnlockWorkingSetShared(v17, v26);
LABEL_46:
MiReleaseFreshPage((_MMPFN *)v25);
goto LABEL_47;
}
_InterlockedAnd64((volatile signed __int64 *)(a2 + 24), 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal(v17, (UINT64)v29);
MiUnlockWorkingSetShared(v17, v26);
v30 = v44;
*a7 = 1;
LABEL_40:
*(_WORD *)(a2 + 32) = 0;
if( a6 )
*a6 = v30;
ExFreePoolWithTag(v11, 0);
return 1i64;
}Referenced by:
MiTradePage