MiMigratePfn

_MMPFN *__stdcall MiMigratePfn(
        _MMSUPPORT_INSTANCE *Vm,
        PVOID FaultingAddress,
        _MMPFN *Pfn1,
        _MMPFN *LockedProtoPfn,
        PVOID TrapInformation,
        _MMINPAGE_SUPPORT **ReadBlock){
  unsigned __int64 v6; 
  _MMPFN *PfnDb; 
  void *v10; 
  _MMSUPPORT_INSTANCE *v11; 
  UINT64 v12; 
  int v13; 
  struct _KPRCB *CurrentPrcb; 
  unsigned int v15; 
  int v16; 
  unsigned int v17; 
  unsigned __int64 v18; 
  void *v19; 
  __int64 v20; 
  UINT8 v21; 
  WCHAR *v22; 
  signed __int32 v23; 
  UNICODE_STRING *v24; 
  unsigned int v25; 
  unsigned int *v26; 
  unsigned int *v27; 
  __int64 v28; 
  __int64 v29; 
  int v30; 
  INT64 v31; 
  _MI_PARTITION *v32; 
  unsigned int v33; 
  unsigned int v34; 
  unsigned int v35; 
  ULONG_PTR Page; 
  UINT64 v37; 
  _MI_PARTITION *v38; 
  char *v40; 
  __int64 v41; 
  __int64 v42; 
  unsigned int *v43; 
  __int64 v44; 
  __int64 v45; 
  _DWORD *v46; 
  _DWORD *v47; 
  unsigned int v48; 
  _MMPTE *v49; 
  INT64 v50; 
  ULONG_PTR v51; 
  __int16 v52; 
  UINT64 v53; 
  INT64 v54; 
  UINT64 v55; 
  _MI_PARTITION *Partition; 
  ULONG_PTR PageFrameIndex; 
  ULONG_PTR BugCheckParameter2; 
  INT64 a9; 
  UINT64 v60; 
  INT64 v61; 
  INT64 v62; 
  UINT64 SpinCount; 
  UINT64 v64; 
  _MMPFN *v65; 
  v65 = LockedProtoPfn;
  v6 = Vm->AgeDistribution[2];
  v60 = *(_QWORD *)&Vm->NextPageColor;
  PageFrameIndex = (ULONG_PTR)Vm->VmWorkingSetList;
  if( (*((_QWORD *)FaultingAddress + 5) & 0x2000000000000i64) != 0 )
    return(_MMPFN *)FaultingAddress;
  PfnDb = MmGetPfnDb();
  if( byte_140C51D9E )
  {
    if( _bittest64(
           (const signed __int64 *)qword_140C522C8,
           (unsigned __int64)(((_BYTE *)FaultingAddress - (_BYTE *)PfnDb) / 48) >> 9) )
    {
      return(_MMPFN *)FaultingAddress;
    }
  }
  if( (unsigned __int16)KeNumberNodes <= 1u
    || *((_WORD *)FaultingAddress + 16)
    || (*((_BYTE *)KeGetCurrentThread() + 1304) & 0x40) != 0
    || !MiCanPageMove((INT64)FaultingAddress) )
  {
    return(_MMPFN *)FaultingAddress;
  }
  v12 = 0i64;
  a9 = 0i64;
  MiComputeFaultNode(v11, 0i64, (_CONTROL_AREA *)&a9, v10, (_MMVAD **)v55);
  if( v13 )
  {
    CurrentPrcb = KeGetCurrentPrcb();
    v15 = (v13 - 1) << byte_140C4DBCC;
  }
  else
  {
    CurrentPrcb = *(&KiProcessorBlock + *((unsigned int *)KeGetCurrentThread() + 147));
    v15 = *((_DWORD *)CurrentPrcb + 8134);
  }
  v16 = (1 << byte_140C4DBCD) - 1;
  if( !v6 || (*(_BYTE *)(v6 + 184) & 7u) >= 2 )
    v6 = (unsigned __int64)CurrentPrcb + 32528;
  v17 = v15 >> byte_140C4DBCC;
  v18 = (__int64)((unsigned __int128)(((_BYTE *)FaultingAddress - (_BYTE *)PfnDb) * (__int128)0x2AAAAAAAAAAAAAABi64) >> 64) >> 3;
  v19 = (void *)((v18 >> 63) + v18);
  BugCheckParameter2 = (ULONG_PTR)v19;
  LODWORD(v20) = MiSearchNumaNodeTable(v19);
  if( v17 == *(_DWORD *)(v20 + 8) )
    return(_MMPFN *)FaultingAddress;
  Partition = *(_MI_PARTITION **)(qword_140C4E388 + 8 * ((*((_QWORD *)FaultingAddress + 5) >> 39) & 0x3FFi64));
  v23 = _InterlockedExchangeAdd((volatile signed __int32 *)v6, 1u);
  v24 = (UNICODE_STRING *)(unsigned __int16)KeNumberNodes;
  v25 = v16 & v23 | v15;
  v26 = (unsigned int *)(qword_140C4DBD8 + 4i64 * v17 * (unsigned __int16)KeNumberNodes);
  v27 = &v26[(unsigned __int16)KeNumberNodes];
  if( v26 < v27 )
  {
    while( 1 )
    {
      LODWORD(v28) = MiSearchNumaNodeTable(v19);
      v29 = *v26;
      if( (_DWORD)v29 == *(_DWORD *)(v28 + 8) )
        return(_MMPFN *)FaultingAddress;
      if( *(_OWORD *)(*((_QWORD *)Partition + 2) + 4544 * v29 + 4128) == 0i64 && ++v26 < v27 )
        continue;
      break;
    }
  }
  LOBYTE(v30) = MI_PFN_IS_PROTO((UNICODE_STRING *)FaultingAddress, v24, v21, v22);
  if( v30 && (*((_DWORD *)FaultingAddress + 4) & 0x400i64) != 0 )
  {
    v34 = v33;
  }
  else
  {
    v34 = 0;
    if( (unsigned int)MiIsPfnCommitNotCharged(v31) )
      v34 = 5;
  }
  if( !(unsigned int)MiObtainFaultCharges(v32, v33, v34) )
    return(_MMPFN *)FaultingAddress;
  v35 = 1;
  if( (PageFrameIndex & 1) != 0 && *(_BYTE *)(PageFrameIndex & 0xFFFFFFFFFFFFFFFEui64) == 4
    || (unsigned int)MiGetSystemRegionType(v60) == 12 )
  {
    v35 = 9;
  }
  Page = MiGetPage(Partition, v25, v35);
  PageFrameIndex = Page;
  if( Page == -1i64 )
  {
    v37 = v34;
    v38 = Partition;
LABEL_31:
    MiReturnFaultCharges(v38, 1ui64, v37);
    return(_MMPFN *)FaultingAddress;
  }
  v40 = (char *)MmGetPfnDb() + 48 * Page;
  v41 = (__int64)(48 * Page) / 48;
  LODWORD(v42) = MiSearchNumaNodeTable((PVOID)v41);
  if( v17 != *(_DWORD *)(v42 + 8) )
  {
    v43 = (unsigned int *)(qword_140C4DBD8 + 4i64 * v17 * (unsigned __int16)KeNumberNodes);
    if( v43 < v27 )
    {
      while( 1 )
      {
        LODWORD(v44) = MiSearchNumaNodeTable((PVOID)BugCheckParameter2);
        if( *v43 == *(_DWORD *)(v44 + 8) )
          goto LABEL_40;
        LODWORD(v45) = MiSearchNumaNodeTable((PVOID)v41);
        if( *v43 != *(_DWORD *)(v45 + 8) && ++v43 < v27 )
          continue;
        break;
      }
    }
  }
  if( Pfn1 )
  {
    v46 = MiGetInPageSupportBlock(6);
    if( !v46 )
    {
LABEL_40:
      MiLockNestedPageAtDpcInline((INT64)v40);
      MiReturnFreeZeroPage((INT64)v40);
      _InterlockedAnd64((volatile signed __int64 *)v40 + 3, 0x7FFFFFFFFFFFFFFFui64);
      v38 = Partition;
      v37 = v34;
      goto LABEL_31;
    }
    v47 = v46;
  }
  else
  {
    v47 = 0i64;
  }
  v48 = *((unsigned __int8 *)FaultingAddress + 34) >> 6;
  MiLockNestedPageAtDpcInline((INT64)v40);
  if( (unsigned __int8)v40[34] >> 6 != v48 )
    MiChangePageAttribute((INT64)v40, v48, 1);
  MiSetPfnTbFlushStamp((_MMPFN *)v40, 0i64, 1ui64);
  MiCopyPfnEntryEx((INT64)v40, (INT64)FaultingAddress);
  *((_WORD *)v40 + 16) = 1;
  *((_QWORD *)v40 + 3) &= 0xC000000000000000ui64;
  *((_BYTE *)FaultingAddress + 34) = *((_BYTE *)FaultingAddress + 34) & 0xF8 | 5;
  if( v47 )
  {
    v47[48] |= 0x20u;
    v40[34] |= 0x20u;
    *(_QWORD *)v40 = v47 + 8;
    *((_QWORD *)v47 + 31) = v40;
  }
  v49 = (_MMPTE *)(*((_QWORD *)v40 + 1) | 0x8000000000000000ui64);
  v50 = MI_READ_PTE_LOCK_FREE((INT64)v49);
  *(_QWORD *)v49 = MiUpdateTransitionPteFrame(v50, PageFrameIndex);
  _InterlockedAnd64((volatile signed __int64 *)v40 + 3, 0x7FFFFFFFFFFFFFFFui64);
  if( Pfn1 )
  {
    MiLockNestedPageAtDpcInline((INT64)Pfn1);
    if( !(unsigned int)MiAreChargesNeededToLockPage((INT64)Pfn1) || (unsigned int)MiChargeForLockedPage((INT64)Pfn1, 3) )
      ++*((_WORD *)Pfn1 + 16);
    _InterlockedAnd64((volatile signed __int64 *)Pfn1 + 3, 0x7FFFFFFFFFFFFFFFui64);
    _InterlockedAnd64((volatile signed __int64 *)FaultingAddress + 3, 0x7FFFFFFFFFFFFFFFui64);
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)Pfn1 + 6, 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( *((__int64 *)Pfn1 + 3) < 0 );
    }
    *((_BYTE *)Pfn1 + 34) &= ~0x20u;
    MiRemoveLockedPageChargeAndDecRef(Pfn1);
    _InterlockedAnd64((volatile signed __int64 *)Pfn1 + 3, 0x7FFFFFFFFFFFFFFFui64);
    *(_QWORD *)v65 = v47;
  }
  else
  {
    _InterlockedAnd64((volatile signed __int64 *)FaultingAddress + 3, 0x7FFFFFFFFFFFFFFFui64);
    __writecr8(2ui64);
  }
  v51 = BugCheckParameter2;
  MiCopyPage(PageFrameIndex, BugCheckParameter2, 0i64, 2);
  if( Pfn1 )
  {
    MiLockProtoPoolPage(v49, 0i64);
    LODWORD(v64) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)Pfn1 + 6, 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&v64);
      while( *((__int64 *)Pfn1 + 3) < 0 );
    }
    MiRemoveLockedPageChargeAndDecRef(Pfn1);
    _InterlockedAnd64((volatile signed __int64 *)Pfn1 + 3, 0x7FFFFFFFFFFFFFFFui64);
    LODWORD(v55) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)FaultingAddress + 6, 0x3Fui64) )
    {
      do
        KeYieldProcessorEx(&v55);
      while( *((__int64 *)FaultingAddress + 3) < 0 );
    }
  }
  else
  {
    MiLockPageInline((INT64)FaultingAddress);
  }
  *((_QWORD *)FaultingAddress + 5) &= 0x8FFFFFFFFFFFFFFFui64;
  MiInsertPageInFreeOrZeroedList(v51, 2ui64);
  _InterlockedAnd64((volatile signed __int64 *)FaultingAddress + 3, 0x7FFFFFFFFFFFFFFFui64);
  HIDWORD(v55) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)v40 + 6, 0x3Fui64) )
  {
    do
      KeYieldProcessorEx((UINT64 *)((char *)&v55 + 4));
    while( *((__int64 *)v40 + 3) < 0 );
  }
  v52 = *((_WORD *)v40 + 16);
  v40[34] &= ~0x20u;
  *(_QWORD *)v40 = 0i64;
  MiRemoveLockedPageCharge((INT64)v40);
  if( !v47 )
    return(_MMPFN *)v40;
  v47[48] &= ~0x20u;
  if( (*((_QWORD *)v40 + 3) & 0x4000000000000000i64) == 0 )
    return(_MMPFN *)v40;
  if( v52 == 1 )
  {
    if( (*((_DWORD *)v40 + 4) & 0x400i64) == 0 )
      v12 = MiCapturePageFileInfoInline((UINT64 *)v40 + 2, 0i64, 1i64);
    MiInsertPageInFreeOrZeroedList(PageFrameIndex, 2ui64);
  }
  _InterlockedAnd64((volatile signed __int64 *)v40 + 3, 0x7FFFFFFFFFFFFFFFui64);
  if( Pfn1 )
  {
    LOBYTE(v53) = 2;
    MiUnlockProtoPoolPage(Pfn1, v53);
  }
  if( v12 )
    MiReleasePageFileInfo(
      (INT64)Partition,
      v12,
      1,
      v54,
      v55,
      (INT64)Partition,
      PageFrameIndex,
      BugCheckParameter2,
      a9,
      v60,
      v61,
      v62);
  return 0i64;
}

Referenced by:

MiHandleTransitionFault