HalpIommuMapLogicalRange
INT64 __fastcall HalpIommuMapLogicalRange(INT64 a1, INT64 a2, UINT64 a3, INT64 a4, INT64 a5, UINT64 a6){
int v6;
UINT64 v8;
__int64 v9;
unsigned __int64 v10;
UINT64 v11;
INT64 v12;
UINT64 v13;
int v14;
UINT64 v15;
unsigned int v16;
unsigned __int64 v17;
__int64 v18;
__int64 v19;
unsigned __int64 v20;
unsigned __int8 v21;
unsigned __int64 v22;
void *v23;
PHYSICAL_ADDRESS PhysicalAddress;
void *v25;
unsigned int v26;
unsigned __int64 v27;
__int64 v28;
int v29;
UINT64 v30;
void *v31;
unsigned int v32;
UINT64 v33;
int v34;
__int64 v35;
__int64 v36;
char v38;
unsigned int v39;
unsigned int v40;
__int64 v41;
INT64 v42;
UINT64 v43;
unsigned __int64 v44;
INT64 v45;
PKSPIN_LOCK SpinLock;
INT64 v47;
__int128 v48[3];
v6 = *(_DWORD *)(a2 + 28);
v8 = a6;
LODWORD(v9) = 0;
v45 = a1;
v10 = *(_QWORD *)(a2 + 16);
v11 = a6 + ((a5 + 4095) & 0xFFFFFFFFFFFFF000ui64);
v39 = a3;
v38 = v6;
v44 = v11;
v47 = a6;
v40 = 1 << v6;
v48[0] = v10;
v12 = a4 & -(__int64)((_DWORD)a3 != 0);
v13 = 0i64;
v42 = v12;
v43 = 0i64;
memset(&v48[1], 0, 32);
if( a6 < v11 )
{
while( 1 )
{
v14 = *(_DWORD *)(a2 + 24);
if( (unsigned int)v9 < v14 - 1 )
{
v15 = (unsigned int)v9;
while( 1 )
{
v16 = *(_DWORD *)(a2 + 4 * v15 + 36);
v17 = v10 + (1 << v16 << v6);
if( v16 < 0x40 )
v18 = (1i64 << v16) - 1;
else
LODWORD(v18) = -1;
v19 = (unsigned int)v18 & (unsigned int)(v8 >> *(_DWORD *)(a2 + 4 * v15 + 60));
v41 = v19;
v20 = *(_QWORD *)(v17 + 8 * v19);
if( !v20 )
{
SpinLock = (PKSPIN_LOCK)(a2 + 8);
KeAcquireSpinLockRaiseToDpc((UINT64 *)(a2 + 8), v15);
v22 = v21;
if( !*(_QWORD *)(v17 + 8 * v19) )
{
v23 = (void *)HalpIommuAllocateAndZeroPageTable(a2, (unsigned int)(v9 + 1), v45);
*(_QWORD *)(v17 + 8 * v19) = v23;
if( !v23 )
{
KxReleaseSpinLock(SpinLock);
__writecr8(v22);
return 3221225626i64;
}
PhysicalAddress = MmGetPhysicalAddress(v23);
v25 = (void *)(v10 + (unsigned int)((_DWORD)v19 << v38));
(**(void(__fastcall ***)(void *, _QWORD, PHYSICAL_ADDRESS))(a2 + 88))(
v25,
(unsigned int)(*(_DWORD *)(a2 + 24) - v9 - 1),
PhysicalAddress);
if( !HalpIommuPageTableCacheCoherent )
KeInvalidateRangeAllCachesNoIpi(v25, v40);
}
KxReleaseSpinLock((UINT64 *)(a2 + 8));
__writecr8(v22);
v14 = *(_DWORD *)(a2 + 24);
LOBYTE(v6) = v38;
v20 = *(_QWORD *)(v17 + 8 * v41);
}
v10 = v20;
v9 = (unsigned int)(v9 + 1);
v15 = (unsigned int)v9;
*((_QWORD *)v48 + v9) = v20;
if( (unsigned int)v9 >= v14 - 1 )
{
v13 = v43;
v12 = v42;
v11 = v44;
LODWORD(a3) = v39;
break;
}
}
}
v26 = *(_DWORD *)(a2 + 4i64 * (unsigned int)v9 + 36);
if( (_DWORD)a3 )
{
if( v26 < 0x40 )
v28 = (1i64 << v26) - 1;
else
LODWORD(v28) = -1;
v29 = v28 & (v8 >> *(_DWORD *)(a2 + 4i64 * (unsigned int)v9 + 60));
v30 = v11 - v8;
v31 = (void *)(v10 + (unsigned int)(v29 << v6));
v32 = (1 << *(_DWORD *)(a2 + 4i64 * (unsigned int)(v14 - 1) + 36)) - v29;
v33 = v30 >> 12;
if( (unsigned int)v33 <= v32 )
v32 = v33;
v34 = (*(__int64(__fastcall **)(unsigned __int64, INT64, _QWORD, _QWORD))(*(_QWORD *)(a2 + 88) + 8i64))(
v10 + (unsigned int)(v29 << v6),
v12,
v39,
v32);
v13 += (unsigned int)(v34 << 12);
v43 = v13;
if( v34 != v32 )
{
HalpIommuUnmapLogicalRange(a2, &v43, v47);
return 3221225485i64;
}
if( !HalpIommuPageTableCacheCoherent )
KeInvalidateRangeAllCachesNoIpi(v31, v40 * v32);
v35 = v32 << 12;
v12 = (unsigned int)v35 + v42;
v42 = v12;
v27 = v35 + v8;
}
else
{
v27 = ~((1i64 << ((unsigned __int8)v26 + 12)) - 1) & ((1i64 << ((unsigned __int8)v26 + 12)) + v8);
}
if( (_DWORD)v9 )
{
do
{
v36 = (unsigned int)(v9 - 1);
if( ((1i64 << *(_DWORD *)(a2 + 4 * v36 + 60)) & v27) == (v8 & (1i64 << *(_DWORD *)(a2 + 4 * v36 + 60))) )
break;
LODWORD(v9) = v9 - 1;
}
while( (_DWORD)v36 );
}
v11 = v44;
v8 = v27;
v10 = *((_QWORD *)v48 + (unsigned int)v9);
if( v27 >= v44 )
return 0i64;
LOBYTE(v6) = v38;
LODWORD(a3) = v39;
}
}
return 0i64;
}Referenced by:
HalpIommuConstructReservedPageTable
HalpIommuDomainMapLogicalRange
IommuMapIdentityRange
IommuMapLogicalRange