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