VmAccessFault

NTSTATUS __stdcall VmAccessFault(
        UINT64 GuestPhysicalAddress,
        VOID *SystemVirtualAddress,
        UINT64 FaultTypeFlags,
        UINT64 PartitionId){
  PSLIST_ENTRY v4; 
  int v5; 
  unsigned __int64 *v7; 
  unsigned __int64 *v8; 
  __int64 v9; 
  _RTL_BALANCED_NODE *p_a2; 
  unsigned __int64 *v11; 
  unsigned __int64 v12; 
  unsigned __int64 v13; 
  INT64 v14; 
  INT64 v15; 
  __int64 v16; 
  int v17; 
  INT64 a5; 
  INT64 a6; 
  INT64 a7; 
  int v22; 
  unsigned __int64 v23; 
  char *v24; 
  volatile int *SpinLock; 
  _RTL_BALANCED_NODE a2; 
  int v27; 
  int v28; 
  INT64 a8; 

  v4 = 0i64;
  v24 = (char *)SystemVirtualAddress;
  v5 = PartitionId;
  v7 = (unsigned __int64 *)SystemVirtualAddress;
  v8 = (unsigned __int64 *)GuestPhysicalAddress;
  if( (PartitionId & 0xFFFFFF80) != 0 )
    NT_ASSERT("(FaultTypeFlags & ~0x7F) == 0");
  SpinLock = (volatile int *)KeGetCurrentThread()->ApcState.Process->VmContext;
  if( !SpinLock )
    NT_ASSERT("ProcessContext != ((void *)0)");
  if( (PartitionId & 0x38) == 32 )
    VmpPrefetchForVirtualFault(GuestPhysicalAddress, (INT64 *)SystemVirtualAddress, FaultTypeFlags);
  v9 = 0i64;
  v22 = 16;
  p_a2 = &a2;
  if( FaultTypeFlags > 0x10 || v8[1] > 0x10 )
  {
    ++dword_140CEE794;
    v4 = RtlpInterlockedPopEntrySList(&VmpLargeFaultBatchLookasideList);
    if( !v4 )
    {
      ++dword_140CEE798;
      v4 = (PSLIST_ENTRY)((__int64(__fastcall *)(_QWORD, _QWORD, _QWORD, _SLIST_HEADER *))qword_140CEE7B0)(
                           (unsigned int)dword_140CEE7A4,
                           (unsigned int)dword_140CEE7AC,
                           (unsigned int)dword_140CEE7A8,
                           &VmpLargeFaultBatchLookasideList);
    }
    if( v4 )
    {
      HIDWORD(v4->Next) = 0;
      p_a2 = (_RTL_BALANCED_NODE *)&v4[2];
      *((_QWORD *)&v4->Next + 1) = v4 + 2;
      v4[1].Next = v4 + 1538;
      *((_QWORD *)&v4[1].Next + 1) = v4 + 1538;
      v22 = 512;
      LODWORD(v4->Next) = 512;
    }
  }
  v11 = &v8[2 * FaultTypeFlags];
  if( v8 >= v11 )
    goto LABEL_29;
  do
  {
    v12 = *v8;
    v13 = *v7;
    v23 = v8[1] + *v8;
    if( VmpTraceLoggingProvider && *(_DWORD *)VmpTraceLoggingProvider && tlgKeywordOn(VmpTraceLoggingProvider, 8i64) )
    {
      LODWORD(a7) = v28;
      LODWORD(a6) = v27;
      LODWORD(a5) = v5;
      VmpLogAccessFault(v14, v13, v12, v15, a5, a6, a7);
    }
    while( v12 < v23 )
    {
      if( v13 > 0x7FFFFFFEFi64 )
        NT_ASSERT("SystemVpn <= ((ULONG_PTR)MmHighestUserAddress >> 12L)");
      v16 = 2 * v9;
      v9 = (unsigned int)(v9 + 1);
      p_a2[v16 + 1].Children[0] = (_RTL_BALANCED_NODE *)(v13 & 0xFFFFFFFFFFFFFi64);
      p_a2[v16 + 1].Children[1] = (_RTL_BALANCED_NODE *)(v12 & 0xFFFFFFFFFFFFFi64);
      if( (_DWORD)v9 == v22 )
      {
        LODWORD(a7) = v28;
        LODWORD(a6) = v27;
        LODWORD(a5) = v5;
        v17 = VmpAccessFaultBatch(SpinLock, p_a2, (unsigned int)v9, (INT64)v4, a5, a6, a7, a8);
        if( v17 < 0 )
          goto LABEL_30;
        v9 = 0i64;
      }
      ++v12;
      ++v13;
    }
    v8 += 2;
    v7 = (unsigned __int64 *)(v24 + 8);
    v24 += 8;
  }
  while( v8 < v11 );
  if( !(_DWORD)v9
    || (LODWORD(a7) = v28,
        LODWORD(a6) = v27,
        LODWORD(a5) = v5,
        v17 = VmpAccessFaultBatch(SpinLock, p_a2, (unsigned int)v9, (INT64)v4, a5, a6, a7, a8),
        v17 >= 0) )
  {
LABEL_29:
    v17 = 0;
  }
LABEL_30:
  if( v4 )
  {
    ++dword_140CEE79C;
    if( LOWORD(VmpLargeFaultBatchLookasideList.Alignment) < (unsigned __int16)word_140CEE790 )
    {
      RtlpInterlockedPushEntrySList(&VmpLargeFaultBatchLookasideList, v4);
    }
    else
    {
      ++dword_140CEE7A0;
      ((void(__fastcall *)(PSLIST_ENTRY, _SLIST_HEADER *))qword_140CEE7B8)(v4, &VmpLargeFaultBatchLookasideList);
    }
  }
  return v17;
}

Referenced by:

No references.