IommuProcessPageRequestQueue

CHAR __fastcall IommuProcessPageRequestQueue(UINT64 a1){
  _QWORD *v1; 
  __int64 v2; 
  __int64 v3; 
  UINT64 v4; 
  unsigned __int64 v5; 
  __int64 v6; 
  signed __int64 v7; 
  void *v8; 
  void *v9; 
  char *v10; 
  UINT64 v11; 
  unsigned __int8 v12; 
  unsigned __int64 v13; 
  __int64 v14; 
  unsigned __int8 CurrentIrql; 
  UINT64 *v16; 
  _QWORD *v17; 
  _QWORD *v18; 
  _QWORD *v19; 
  _QWORD *v20; 
  _QWORD *i; 
  _DWORD *v22; 
  __int64 v23; 
  __int64 v24; 
  int v25; 
  int v26; 
  UINT64 v27; 
  int v28; 
  int v29; 
  void *v30; 
  __int64 v31; 
  unsigned __int8 v32; 
  unsigned __int64 v33; 
  int v35; 
  void *v36; 
  char v38[4]; 
  unsigned __int16 v39; 
  unsigned int v40; 
  int v41; 
  void *Src; 
  __int64 v43; 
  __int64 v44; 
  __int64 v45; 
  __int64 v46; 
  v40 = 0;
  v46 = 0i64;
  v44 = 0i64;
  v39 = 0;
  v41 = 0;
  if( HalpHvIommu )
  {
    v1 = (_QWORD *)(IommupHvPageRequestQueues + ((unsigned __int64)(unsigned int)a1 << 6));
    v3 = (__int64)v1;
    v4 = (UINT64)(v1 + 3);
  }
  else
  {
    v1 = (_QWORD *)HalpIommuList;
    if( (_DWORD)a1 )
    {
      v2 = (unsigned int)a1;
      do
      {
        v1 = (_QWORD *)*v1;
        --v2;
      }
      while( v2 );
    }
    v3 = v1[2];
    v4 = (UINT64)(v1 + 48);
  }
  v45 = 0i64;
  v5 = *(unsigned int *)(v4 + 20);
  v6 = v5 + 15;
  v43 = v3;
  if( v5 + 15 <= v5 )
    v6 = 0xFFFFFFFFFFFFFF0i64;
  v7 = v6 & 0xFFFFFFFFFFFFFFF0ui64;
  v8 = alloca(v7);
  v9 = alloca(v7);
  v38[0] = 0;
  v10 = v38;
  Src = v38;
  ExAcquirePushLockSharedEx(v4, 0i64);
  while( 1 )
  {
    KeAcquireSpinLockRaiseToDpc((UINT64 *)(v4 + 8), v11);
    v13 = v12;
    if( !(*(unsigned int(__fastcall **)(__int64, char *, unsigned int *, __int64 *, unsigned __int16 *, int *, __int64 *, __int64 *))(v4 + 24))(
            v3,
            v10,
            &v40,
            &v45,
            &v39,
            &v41,
            &v46,
            &v44) )
      break;
    v38[0] = 1;
    if( (v44 & 0x40) != 0 )
    {
      ++*(_DWORD *)(v4 + 16);
      KxReleaseSpinLock((UINT64 *)(v4 + 8));
      __writecr8(v13);
    }
    else
    {
      v14 = *(_QWORD *)((*(__int64(__fastcall **)(_QWORD))(HalIommuDispatch + 104))(v40) + 8);
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(0xFui64);
      v16 = (UINT64 *)(v14 + 24);
      KxAcquireSpinLock((UINT64 *)(v14 + 24));
      v17 = *(_QWORD **)(v14 + 40);
      v18 = 0i64;
      while( v17 != (_QWORD *)(v14 + 40) )
      {
        v18 = v17;
        if( (_QWORD *)v17[2] == v1 )
          break;
        v17 = (_QWORD *)*v17;
      }
      v19 = v18 + 3;
      v20 = 0i64;
      for( i = (_QWORD *)*v19; i != v19; i = (_QWORD *)*i )
      {
        v20 = i;
        if( *(_QWORD *)(i[5] + 40i64) == v45 )
          break;
      }
      KxReleaseSpinLock(v16);
      __writecr8(CurrentIrql);
      if( *((_BYTE *)v20 + 56) )
      {
        KxReleaseSpinLock((UINT64 *)(v4 + 8));
        __writecr8(v13);
        (*(void(__fastcall **)(_QWORD))(HalIommuDispatch + 112))(v40);
        v10 = (char *)Src;
        v3 = v43;
      }
      else
      {
        if( *((_DWORD *)v20 + 15) != *(_DWORD *)(v4 + 16) )
        {
          v22 = v20 + 10;
          v23 = 512i64;
          do
          {
            *v22 &= ~2u;
            *(v22 - 4) = 0;
            v22 += 6;
            --v23;
          }
          while( v23 );
          *((_DWORD *)v20 + 15) = *(_DWORD *)(v4 + 16);
        }
        v24 = 3i64 * v39;
        v25 = v20[3 * v39 + 10];
        ++LODWORD(v20[3 * v39 + 8]);
        v26 = v25 & 2;
        if( (v44 & 0x10) != 0 )
        {
          LODWORD(v20[v24 + 10]) = v25 | 1;
          v20[v24 + 9] ^= (LODWORD(v20[v24 + 9]) ^ v41) & 0x7FFFFF;
          if( HalpHvIommu )
            memmove(
              (UINT8 *)(v20[1544] + *(_DWORD *)(v4 + 20) * (unsigned int)v39),
              (UINT8 *)Src,
              *(unsigned int *)(v4 + 20));
        }
        KxReleaseSpinLock((UINT64 *)(v4 + 8));
        __writecr8(v13);
        v28 = (*(__int64(__fastcall **)(__int64, __int64, _QWORD))(HalIommuDispatch + 120))(v44, v46, v40);
        v29 = 0;
        if( HalpHvIommu && v28 >= 0 && !v26 && (v44 & 0x30) == 0 )
        {
          if( !IommupHvGpaAlwaysValid )
          {
            v30 = Src;
            *((_QWORD *)Src + 4) |= 0x4000000000000000ui64;
            v29 = ((__int64(__fastcall *)(__int64, void *, _QWORD))qword_140C4A260)(1i64, v30, 0i64);
          }
          v28 = v29;
        }
        KeAcquireSpinLockRaiseToDpc((UINT64 *)(v4 + 8), v27);
        v33 = v32;
        if( v28 < 0 )
          LODWORD(v20[v24 + 10]) |= 2u;
        if( LODWORD(v20[v24 + 8])-- == 1 )
        {
          v35 = v20[v24 + 10];
          if( (v35 & 1) != 0 )
          {
            if( (v35 & 2) != 0 )
              v28 = -1073741823;
            if( HalpHvIommu )
              v36 = (void *)(v20[1544] + *(_DWORD *)(v4 + 20) * (unsigned int)v39);
            else
              v36 = Src;
            LOBYTE(v31) = 1;
            (*(void(__fastcall **)(__int64, void *, _QWORD, __int64, int))(v4 + 32))(
              v43,
              v36,
              (unsigned int)v28,
              v31,
              v20[v24 + 9] & 0x7FFFFF);
            LODWORD(v20[v24 + 10]) &= 0xFFFFFFFC;
LABEL_46:
            v3 = v43;
            v10 = (char *)Src;
            goto LABEL_47;
          }
        }
        if( (v44 & 0x20) == 0 )
          goto LABEL_46;
        v10 = (char *)Src;
        v3 = v43;
        (*(void(__fastcall **)(__int64, void *, _QWORD, _QWORD, int))(v4 + 32))(v43, Src, (unsigned int)v28, 0i64, v41);
LABEL_47:
        KxReleaseSpinLock((UINT64 *)(v4 + 8));
        __writecr8(v33);
        (*(void(__fastcall **)(_QWORD))(HalIommuDispatch + 112))(v40);
      }
    }
  }
  KxReleaseSpinLock((UINT64 *)(v4 + 8));
  __writecr8(v13);
  if( _InterlockedCompareExchange64((volatile signed __int64 *)v4, 0i64, 17i64) != 17 )
    ExfReleasePushLockShared((INT64 *)v4);
  KeAbPostRelease((PVOID)v4);
  return v38[0];
}

Referenced by:

No references.