MiGetEnclavePage
NTSTATUS __stdcall MiGetEnclavePage(_MI_PARTITION *Partition, UINT64 AlreadyCharged){
int v2;
unsigned __int8 CurrentIrql;
NTSTATUS v5;
_MMPFN *PfnDb;
unsigned __int64 Flink;
_MMPFN *v8;
__int64 v9;
__int64 v10;
_MMPFN *v11;
_KLOCK_QUEUE_HANDLE LockQueue;
UINT64 SpinCount;
int v15;
v15 = AlreadyCharged;
v2 = AlreadyCharged;
*(_QWORD *)&LockQueue.OldIrql = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v5 = -1;
LockQueue.LockQueue.Next = 0i64;
LockQueue.LockQueue.Lock = &Partition->PageLists.EnclavePageListHead.Lock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &Partition->PageLists.EnclavePageListHead.Lock);
PfnDb = MmGetPfnDb();
while( 1 )
{
if( !v2 && !Partition->PageLists.EnclavePageListHead.Total )
{
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
goto LABEL_20;
}
Flink = Partition->PageLists.EnclavePageListHead.Flink;
v8 = &PfnDb[Flink];
if( !_interlockedbittestandset64((volatile signed __int32 *)&v8->u2, 0x3Fui64) )
break;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v8->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v8->u2._bf_0 < 0 );
}
LockQueue.LockQueue.Lock = &Partition->PageLists.EnclavePageListHead.Lock;
LockQueue.LockQueue.Next = 0i64;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &Partition->PageLists.EnclavePageListHead.Lock);
PfnDb = MmGetPfnDb();
if( (*((_BYTE *)&v8->u3 + 3) & 0x10) != 0 )
break;
_InterlockedAnd64(&v8->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v2 = v15;
}
v9 = v8->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFi64;
v10 = v8->u2._bf_0 & 0xFFFFFFFFFi64;
if( v9 == 0xFFFFFFFFFi64 )
Partition->PageLists.EnclavePageListHead.Blink = v10;
else
MiSetPfnBlink(&PfnDb[v9], v8->u2._bf_0 & 0xFFFFFFFFFi64, 0i64);
if( v10 == 0xFFFFFFFFFi64 )
{
Partition->PageLists.EnclavePageListHead.Flink = v9;
}
else
{
v11 = &MmGetPfnDb()[v10];
v11->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 = v9 | v11->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFF000000000ui64;
}
if( !v15 )
--Partition->PageLists.EnclavePageListHead.Total;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
*((_BYTE *)&v8->u3 + 3) &= ~0x10u;
_InterlockedAnd64(&v8->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v5 = Flink;
LABEL_20:
__writecr8(CurrentIrql);
return v5;
}Referenced by:
MiAllocateMdlPagesByLists
MiCreateHardwareEnclave
MiGetPageForEnclave
MiInitializeEnclaveMetadataPage
MiReserveEnclavePages