IvtFlushTbInternal
CHAR __fastcall IvtFlushTbInternal(
_QWORD *a1,
INT64 a2,
INT64 a3,
CHAR a4,
CHAR a5,
INT64 a6,
INT64 a7,
INT64 a8,
INT64 a9){
CHAR v9;
int v10;
unsigned __int64 v12;
unsigned __int64 v13;
INT64 v14;
WORK_QUEUE_TYPE v15;
void *v16;
__int64 v17;
_QWORD *v18;
unsigned __int64 v19;
__int16 v20;
unsigned __int16 v21;
__int64 v22;
int v23;
unsigned __int64 v24;
__int64 v25;
unsigned __int64 v26;
unsigned int v27;
int v28;
unsigned __int64 v29;
unsigned int v30;
__int16 v31;
unsigned __int64 v32;
unsigned __int64 v33;
_QWORD *v34;
_BYTE *v35;
CHAR result;
struct _EX_RUNDOWN_REF *v37;
_BYTE *v38;
PEX_RUNDOWN_REF RunRef;
_QWORD a2a[2];
__int64 a3a;
_QWORD *v42;
_QWORD v43[2];
__int128 LockHandle;
__int64 LockHandle_16;
__int64 v46;
unsigned int v47;
int a4a;
v9 = a5;
v10 = a8;
LockHandle_16 = 0i64;
RunRef = 0i64;
v38 = 0i64;
a4a = 0;
*(_OWORD *)v43 = 0i64;
a3a = 0i64;
v12 = (-(__int64)(a5 != 0) & 0xFFFFFFFFFFFFFFFCui64) + 6;
LockHandle = 0i64;
*(_OWORD *)a2a = 0i64;
if( !(_DWORD)a8 )
{
if( a4 )
{
if( a5 )
v13 = v12 & 0xFFFFFFFFFFFFFFCFui64 | 0x10;
else
v13 = v12 & 0xFFFFFFFFFFFFFFCFui64;
}
else
{
if( a5 )
{
a2a[0] = v12 & 0xFFFFFFFF0000FFEFui64 | ((unsigned __int64)(unsigned __int16)a3 << 16) | 0x20;
goto LABEL_10;
}
v13 = v12 & 0xFFF00000FFFFFFCFui64 | 0x20;
}
a2a[0] = v13;
LABEL_10:
IvtIommuSendCommand(a1, a2a, 0i64);
if( v9 )
goto LABEL_48;
v42 = 0i64;
v43[1] = 0x8000000000000800ui64;
*((_QWORD *)&LockHandle + 1) = a1 + 21;
v17 = 8i64;
*(_QWORD *)&LockHandle = 0i64;
KxAcquireQueuedSpinLock((PIO_WORKITEM)&LockHandle, (PIO_WORKITEM_ROUTINE)(a1 + 21), v15, v16);
v18 = (_QWORD *)a7;
while( HalpIommuGetNextFlushDevice(v18, &v42, &a3a, &a4a, &RunRef, &v38) )
{
if( ExAcquireRundownProtection(RunRef) )
{
v19 = (unsigned __int64)(unsigned __int16)a3a << 12;
*v38 = 1;
v43[0] = v17 & 0xFFFFFFFF0000FE0Fui64 | (16 * (a4a & 0x1F | v19));
IvtIommuSendCommand(a1, v43, 1i64);
v17 = v43[0];
}
}
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
goto LABEL_49;
}
v20 = a2a[1];
if( a5 )
{
a3 = v12 ^ (v12 ^ (a3 << 16)) & 0xFFFF0000 | 0xF0;
a2a[0] = a3;
}
else
{
a2a[0] = v12 & 0xFFF00000FFFFFFCFui64 | 0x30;
v20 = LOWORD(a2a[1]) | 0x80;
}
*(_QWORD *)&LockHandle = 0i64;
v21 = v20 & 0xFFBF;
*((_QWORD *)&LockHandle + 1) = a1 + 21;
KxAcquireQueuedSpinLock((PIO_WORKITEM)&LockHandle, (PIO_WORKITEM_ROUTINE)(a1 + 21), (WORK_QUEUE_TYPE)a3, (PVOID)a4);
while( 2 )
{
v22 = (unsigned int)(v10 - 1);
v23 = 0;
LODWORD(a6) = 0;
LODWORD(a8) = v22;
v24 = *(_QWORD *)(a9 + 8 * v22);
v25 = (v24 >> 10) & 3;
if( ((v24 >> 10) & 3) != 0 )
{
v23 = 9 * v25;
LODWORD(a6) = 9 * v25;
}
v26 = v24 & 0xFFFFFFFFFFFFF000ui64;
v27 = (*(_DWORD *)(a9 + 8 * v22) & 0x3FF) + 1;
v47 = v27;
while( 1 )
{
v28 = 0;
v29 = v26 ^ ((unsigned __int16)v26 ^ v21) & 0xFFF;
if( v27 > 1 )
{
do
{
if( (((1 << (v23 + 13 + v28)) - 1) & (unsigned int)v26) != 0 )
break;
++v28;
}
while( 1 << v28 < v27 );
}
v30 = v27 < 1 << v28 ? (1 << v28) - v27 : 0;
if( v30 >= 0x1F || v23 == 9 && v30 )
--v28;
v46 = (unsigned int)(v28 + v23);
a2a[1] = ((unsigned __int8)v29 ^ (unsigned __int8)(v28 + v23)) & 0x3F ^ v29;
IvtIommuSendCommand(a1, a2a, 1i64);
if( *(_QWORD *)a7 != a7 && !v9 )
{
v31 = 0;
v32 = v26;
v33 = 8i64;
if( v28 || (_DWORD)a6 )
{
v31 = 2048;
v32 = (unsigned int)~(1 << (v46 + 11)) & (v26 | (unsigned int)((1 << (v46 + 11)) - 1));
}
v34 = (_QWORD *)a7;
v42 = 0i64;
v43[1] = v32 ^ ((unsigned __int16)v32 ^ (unsigned __int16)v31) & 0xFFF;
while( 1 )
{
while( 1 )
{
if( !HalpIommuGetNextFlushDevice(v34, &v42, &a3a, &a4a, &RunRef, &v38) )
{
v27 = v47;
v9 = a5;
goto LABEL_42;
}
v33 = v33 & 0xFFFFFFFF0000FE0Fui64 | (16 * (a4a & 0x1F | ((unsigned __int64)(unsigned __int16)a3a << 12)));
v35 = v38;
v43[0] = v33;
if( !*v38 )
break;
LABEL_40:
*v35 = 1;
IvtIommuSendCommand(a1, v43, 1i64);
v33 = v43[0];
}
if( ExAcquireRundownProtection(RunRef) )
{
v35 = v38;
goto LABEL_40;
}
}
}
LABEL_42:
if( v27 <= 1 << v28 )
break;
v27 -= 1 << v28;
v47 = v27;
v26 += 1i64 << ((unsigned __int8)v46 + 12);
if( !v27 )
break;
v21 = a2a[1];
v23 = a6;
}
v10 = a8;
if( (_DWORD)a8 )
{
v21 = a2a[1];
continue;
}
break;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel((_KLOCK_QUEUE_HANDLE *)&LockHandle);
LABEL_48:
v18 = (_QWORD *)a7;
LABEL_49:
result = IvtIommuWaitCommand((INT64)a1, v14, 0i64);
v42 = 0i64;
if( !v9 )
{
while( 1 )
{
result = HalpIommuGetNextFlushDevice(v18, &v42, &a3a, &a4a, &RunRef, &v38);
if( !result )
break;
if( *v38 )
{
v37 = RunRef;
*v38 = 0;
ExReleaseRundownProtection(v37);
}
}
}
return result;
}Referenced by:
IvtAttachDeviceDomainInternal
IvtFlushDomainTb
IvtInitializeIommu