MiDemoteValidLargePageOneLevel
NTSTATUS __stdcall MiDemoteValidLargePageOneLevel(UINT64 Va){
NTSTATUS v2;
UINT64 v3;
_MMPTE *PteBase;
unsigned __int64 v5;
__int64 v6;
INT64 v7;
__int16 v8;
unsigned __int64 v9;
void *v10;
__int64 v11;
_MI_SYSTEM_VA_TYPE v12;
int v13;
UINT64 v15;
__int64 v16;
INT64 v17;
unsigned __int64 v18;
INT64 v19;
INT64 v20;
INT64 v21;
UINT64 v22;
unsigned __int64 v23;
unsigned __int64 v24;
int v25;
int v26;
unsigned int v27;
unsigned int v28;
INT64 v29;
INT64 v30;
INT64 v31;
UINT64 v32;
UINT64 v33;
INT64 v34;
_MMPFN *v35;
UINT64 v36;
__int64 v37;
__int64 v38;
UINT64 i;
UINT64 v40;
UINT64 v41;
UINT64 BitsMustBeChanged;
UINT8 OldIrql[8];
INT64 v44;
UINT64 PageTableCount;
NTSTATUS v46;
int v47;
UINT64 SpinCount;
UINT64 PageFrameIndex;
INT64 v50;
VOID *VirtualAddress;
INT64 v52;
UINT64 ContainingPageFrame;
__int64 v54;
_MI_ZERO_PAGE_TABLE_CREATION PageTableCreation[76];
_MI_TB_FLUSH_LIST TbFlushList[48];
PageTableCount = 0i64;
OldIrql[0] = 0;
memset(TbFlushList, 0i64, 0xB8u);
memset(PageTableCreation, 0i64, 0x128u);
TbFlushList[2] = 20;
*(_QWORD *)&TbFlushList[6] = 0i64;
v46 = MI_IS_PHYSICAL_ADDRESS((VOID *)Va);
v2 = v46;
v3 = (UINT64)MmGetPdeBase() + ((Va >> 18) & 0x3FFFFFF8);
PteBase = MmGetPteBase();
v5 = 0x200000i64;
if( v46 != 1 )
{
v6 = (unsigned int)(v46 - 1);
do
{
v3 = (UINT64)PteBase + ((v3 >> 9) & 0x7FFFFFFFF8i64);
v5 <<= 9;
--v6;
}
while( v6 );
}
LODWORD(v7) = MI_READ_PTE_LOCK_FREE(v3);
v50 = v7;
v8 = v7;
LODWORD(v9) = MI_READ_PTE_LOCK_FREE((INT64)&v50);
PageTableCreation[14] = 4;
v10 = (void *)((v9 >> 12) & 0xFFFFFFFFFi64);
*(_QWORD *)&PageTableCreation[8] = &Irp;
v52 = (INT64)v10;
LODWORD(v11) = MiSearchNumaNodeTable(v10);
MiInitializeColorBase((VOID *)Va, (_MI_COLOR_BASE *)(unsigned int)(*(_DWORD *)(v11 + 8) + 1));
MiGetPageTablePages(PageTableCreation, (VOID *)1, (UINT64)&PageTableCount, v12);
if( v13 < 0 )
return 0;
v15 = PageTableCount;
*(_QWORD *)PageTableCount = 0i64;
v16 = (__int64)(v15 - (_QWORD)MmGetPfnDb()) / 48;
PageFrameIndex = v16;
LODWORD(v17) = MI_READ_PTE_LOCK_FREE((INT64)MmGetPteBase() + ((v3 >> 9) & 0x7FFFFFFFF8i64));
v44 = v17;
LODWORD(v18) = MI_READ_PTE_LOCK_FREE((INT64)&v44);
v19 = 2147483652i64;
ContainingPageFrame = (v18 >> 12) & 0xFFFFFFFFFi64;
if( (v8 & 0x100) != 0 && v2 == 1 )
v19 = 2684354564i64;
v54 = (v3 << 25) - ((_QWORD)MmGetPteBase() << 25);
LODWORD(v20) = MiMakeValidPte((_XSTATE_CONFIGURATION *)(v54 >> 16), (INT64)v10, v19);
v44 = v20;
v21 = v20;
VirtualAddress = MiMapPageInHyperSpaceWorker(v16, OldIrql, 0x80000000ui64);
v22 = (UINT64)VirtualAddress;
v23 = v21;
do
{
*(_DWORD *)&OldIrql[4] = 0;
v24 = v23;
LOBYTE(v25) = MiPteInShadowRange(v22);
if( v25 && (v21 = v44, (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0) )
{
v26 = *(_DWORD *)&OldIrql[4];
if( (v23 & 1) != 0 )
v24 = v23 | 0x8000000000000000ui64;
}
else
{
v26 = *(_DWORD *)&OldIrql[4];
}
*(_QWORD *)v22 = v24;
if( v26 )
MiWritePteShadow();
v22 += 8i64;
v21 ^= (v21 ^ ((v21 & 0xFFFFFFFFFFFFF000ui64) + 4096)) & 0xFFFFFFFFF000i64;
v44 = v21;
v23 = v21;
}
while( (v22 & 0xFFF) != 0 );
MiUnmapPageInHyperSpaceWorker(VirtualAddress, OldIrql[0], 0x80000000ui64);
v27 = v46;
v28 = -2080374780;
v29 = v52;
if( v46 == 1 )
v28 = -2147483644;
v30 = v28;
LODWORD(v30) = v28 | 0x20000000;
if( (v50 & 0x100) == 0 )
v30 = v28;
LODWORD(v30) = v30 | 0x8000000;
LODWORD(v31) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v3, v52, v30);
v32 = PageFrameIndex;
v44 = v31;
MiInitializePfnForOtherProcess(PageFrameIndex, (_MMPTE *)v3, ContainingPageFrame, 0xA00ui64);
v47 = 0;
v33 = PageTableCount;
while( _interlockedbittestandset64((volatile signed __int32 *)(v33 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)&v47);
while( *(__int64 *)(v33 + 24) < 0 );
}
*(_QWORD *)(v33 + 24) ^= (*(_QWORD *)(v33 + 24) ^ (*(_QWORD *)(v33 + 24) + 512i64)) & 0x3FFFFFFFFFFFFFFFi64;
_InterlockedAnd64((volatile signed __int64 *)(v33 + 24), 0x7FFFFFFFFFFFFFFFui64);
PageFrameIndex = v32 & 0xFFFFFFFFFi64;
v44 = ((v32 & 0xFFFFFFFFFi64) << 12) | v44 & 0xFFFF000000000FFFui64;
MiTransformValidPteInPlace((INT64 *)v3, v3, v44, v27);
if( v27 == 3 )
MiInsertLargeTbFlushEntry(TbFlushList, 3ui64, v3);
v35 = &MmGetPfnDb()[v29];
v36 = PageFrameIndex;
v37 = (v54 + 0x10000000) >> 16;
v38 = 512i64;
for( i = (UINT64)&v35[512]; ; i = PageTableCount )
{
v40 = i - 48;
v37 -= 8i64;
LODWORD(SpinCount) = 0;
PageTableCount = v40;
while( _interlockedbittestandset64((volatile signed __int32 *)(v40 + 24), 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)(v40 + 24) < 0 );
}
v41 = PageTableCount;
if( (*(_BYTE *)(PageTableCount + 35) & 0x10) == 0 )
{
if( (*(_QWORD *)(PageTableCount + 40) & 0x1000000000i64) != 0 )
MiConvertLargePfnToSmall((INT64)v35, PageTableCount, v34, 0i64);
*(_QWORD *)(v41 + 8) = v37;
*(_QWORD *)(v41 + 40) = v36 | *(_QWORD *)(v41 + 40) & 0xFFFFFFF000000000ui64;
}
_InterlockedAnd64((volatile signed __int64 *)(v41 + 24), 0x7FFFFFFFFFFFFFFFui64);
if( !--v38 )
break;
}
if( v46 == 1 )
{
LODWORD(BitsMustBeChanged) = 1;
MiUpdateLargePageBitMap((UINT64)&Irp, v29, v5 >> 12, 0i64, BitsMustBeChanged);
}
MiFlushTbList(TbFlushList);
return 1;
}Referenced by:
MiPfnRangeIsZero