ExShareAddressSpaceWithDevice
NTSTATUS __stdcall ExShareAddressSpaceWithDevice(_DEVICE_OBJECT *PhysicalDeviceObject, UINT64 *ReturnedAsid){
__int64 v2;
unsigned int v5;
VOID **v6;
VOID *v7;
_ETHREAD *CurrentThread;
_EPROCESS *Process;
_ETHREAD *v11;
_EX_PUSH_LOCK *p_SvmProcessLock;
__int64 v13;
__int64 AbOrphanedEntrySummary;
char v15;
NTSTATUS SessionId;
bool v17;
unsigned int DeviceAsid;
unsigned int Asid;
int v20;
unsigned __int8 v21;
VOID **v22;
VOID ***v23;
unsigned __int8 CurrentIrql;
_ETHREAD *v25;
__int64 v26;
__int64 v27;
char v28;
__int64 v29;
NTSTATUS v30;
_EXP_SVM_DEVICE *v31;
_EXP_SVM_DEVICE *v32;
_EXP_SVM_DEVICE *v33;
_ETHREAD *v34;
unsigned int v35;
unsigned __int8 v36;
int v37;
__int64 v38;
_KLOCK_ENTRY *v39;
int v40;
unsigned int v41;
unsigned __int8 v42;
VOID **PoolWithTag;
char v44;
unsigned __int8 v45;
_LIST_ENTRY *p_SvmProcessDeviceListHead;
_LIST_ENTRY *Flink;
_LIST_ENTRY *v48;
_ETHREAD *v49;
unsigned __int8 v50;
int v51;
_KLOCK_ENTRY *v52;
__int64 v53;
int v54;
unsigned int v55;
__int64 v56;
VOID *IommuContext;
_EXP_SVM_DEVICE *Device;
UINT64 v59;
UINT64 v60;
UINT64 a3;
UINT64 v62;
_KLOCK_QUEUE_HANDLE LockHandle;
_ETHREAD *v64;
_EXP_SVM_DEVICE *DeviceOut[18];
int Interface;
v2 = 0i64;
IommuContext = 0i64;
memset(DeviceOut, 0i64, 0x50u);
v5 = -1;
Device = 0i64;
*(_DWORD *)ReturnedAsid = -1;
memset(&LockHandle, 0, sizeof(LockHandle));
v6 = 0i64;
v7 = 0i64;
if( !*(&WheapDeferredInternalLogsEventLock + 298) )
return -1073741637;
if( !PhysicalDeviceObject )
return -1073741585;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v64 = CurrentThread;
Process = CurrentThread->Tcb.ApcState.Process;
if( !ExAcquireRundownProtection(&Process->RundownProtect) )
return -1073741558;
Interface = IoQueryInterface(
(INT64)PhysicalDeviceObject,
0,
(INT64)&GUID_IOMMU_BUS_INTERFACE,
0x50u,
1,
(INT64)PhysicalDeviceObject,
(INT64)DeviceOut);
if( Interface >= 0 )
{
--CurrentThread->Tcb.SpecialApcDisable;
v11 = (_ETHREAD *)KeGetCurrentThread();
p_SvmProcessLock = &Process->SvmProcessLock;
LODWORD(a3) = 0;
--v11->Tcb.SpecialApcDisable;
if( ++v11->Tcb.AbAllocationRegionCount != 1 )
KeBugCheckEx(0x192u, v11, &Process->SvmProcessLock, (PVOID)KeGetCurrentIrql(), 0i64);
LOBYTE(v13) = v11->Tcb.AbEntrySummary;
HIDWORD(v60) = 0;
if( !(_BYTE)v13 )
{
if( !v11->Tcb.AbOrphanedEntrySummary )
goto LABEL_14;
AbOrphanedEntrySummary = v11->Tcb.AbOrphanedEntrySummary;
v11->Tcb.AbOrphanedEntrySummary = 0;
LOBYTE(v13) = AbOrphanedEntrySummary | v11->Tcb.AbEntrySummary;
}
v15 = v13;
_BitScanForward((unsigned int *)&v13, (unsigned __int8)v13);
HIDWORD(v60) = v13;
v11->Tcb.AbEntrySummary = v15 & ~(1 << v13);
v2 = (__int64)&v11->Tcb.LockEntries[v13];
if( v2 )
{
if( (unsigned __int64)p_SvmProcessLock >= 0xFFFF800000000000ui64
&& *((_BYTE *)&MiState[1537] + (((unsigned __int64)p_SvmProcessLock >> 39) & 0x1FF)) == 1 )
{
SessionId = MmGetSessionIdEx(v11->Tcb.ApcState.Process);
}
else
{
SessionId = -1;
}
*(_DWORD *)(v2 + 40) = SessionId;
*(_QWORD *)(v2 + 32) = (unsigned __int64)p_SvmProcessLock & 0x7FFFFFFFFFFFFFFCi64;
LABEL_21:
--v11->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v11->Tcb, &Process->SvmProcessLock, &a3);
v17 = v11->Tcb.SpecialApcDisable++ == -1;
if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v11->Tcb.ApcState.ApcListHead[0].Flink != &v11->Tcb.152 )
KiCheckForKernelApcDelivery();
if( _interlockedbittestandset64((volatile signed __int32 *)p_SvmProcessLock, 0i64) )
ExfAcquirePushLockExclusiveEx(&Process->SvmProcessLock, (VOID *)v2, &Process->SvmProcessLock);
if( v2 )
*(_BYTE *)(v2 + 26) |= 1u;
DeviceAsid = Process->DeviceAsid;
if( !DeviceAsid )
{
Asid = ExpAllocateAsid();
DeviceAsid = Asid;
if( !Asid )
{
v20 = -1073741709;
Interface = -1073741709;
goto LABEL_31;
}
if( !(unsigned int)ExpAssignPasid(Process, Asid) )
DeviceAsid = Process->DeviceAsid;
}
--DeviceAsid;
IommuContext = Process->SvmData;
if( !IommuContext )
{
Interface = (*((__int64(__fastcall **)(_QWORD, _QWORD, VOID **))HalIommuDispatch + 2))(
DeviceAsid,
0i64,
&IommuContext);
v20 = Interface;
if( Interface < 0 )
goto LABEL_31;
CurrentIrql = KeGetCurrentIrql();
__writecr8(0xFui64);
KeAcquireInStackQueuedSpinLockAtDpcLevel(&Process->SvmLock, &LockHandle);
if( Process->SvmData )
{
v7 = IommuContext;
IommuContext = Process->SvmData;
}
else
{
Process->SvmData = IommuContext;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(CurrentIrql);
if( v7 )
(*((void(__fastcall **)(VOID *))HalIommuDispatch + 8))(v7);
}
v25 = (_ETHREAD *)KeGetCurrentThread();
LODWORD(v62) = 0;
--v25->Tcb.SpecialApcDisable;
if( ++v25->Tcb.AbAllocationRegionCount != 1 )
KeBugCheckEx(0x192u, v25, (char *)&WheapDeferredInternalLogsEventLock + 2280, (PVOID)KeGetCurrentIrql(), 0i64);
HIDWORD(a3) = 0;
LOBYTE(v26) = v25->Tcb.AbEntrySummary;
if( !(_BYTE)v26 )
{
if( !v25->Tcb.AbOrphanedEntrySummary )
{
v29 = 0i64;
goto LABEL_57;
}
v27 = v25->Tcb.AbOrphanedEntrySummary;
v25->Tcb.AbOrphanedEntrySummary = 0;
LOBYTE(v26) = v27 | v25->Tcb.AbEntrySummary;
}
v28 = v26;
_BitScanForward((unsigned int *)&v26, (unsigned __int8)v26);
HIDWORD(a3) = v26;
v25->Tcb.AbEntrySummary = v28 & ~(1 << v26);
v29 = (__int64)&v25->Tcb.LockEntries[v26];
if( v29 )
{
if( (unsigned __int64)&WheapDeferredInternalLogsEventLock + 2280 >= 0xFFFF800000000000ui64
&& *((_BYTE *)&MiState[1537] + ((((unsigned __int64)&WheapDeferredInternalLogsEventLock + 2280) >> 39) & 0x1FF)) == 1 )
{
v30 = MmGetSessionIdEx(v25->Tcb.ApcState.Process);
}
else
{
v30 = -1;
}
*(_DWORD *)(v29 + 40) = v30;
*(_QWORD *)(v29 + 32) = ((unsigned __int64)&WheapDeferredInternalLogsEventLock + 2280) & 0x7FFFFFFFFFFFFFFCi64;
goto LABEL_60;
}
LABEL_57:
_interlockedbittestandset((volatile signed __int32 *)&v25->Tcb.116 + 1, 0x10u);
LABEL_60:
--v25->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v25->Tcb, (char *)&WheapDeferredInternalLogsEventLock + 2280, &v62);
v17 = v25->Tcb.SpecialApcDisable++ == -1;
if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v25->Tcb.ApcState.ApcListHead[0].Flink != &v25->Tcb.152 )
KiCheckForKernelApcDelivery();
if( _interlockedbittestandset64((volatile signed __int32 *)&WheapDeferredInternalLogsEventLock + 570, 0i64) )
ExfAcquirePushLockExclusiveEx(
(_EX_PUSH_LOCK *)&WheapDeferredInternalLogsEventLock + 285,
(VOID *)v29,
(char *)&WheapDeferredInternalLogsEventLock + 2280);
if( v29 )
*(_BYTE *)(v29 + 26) |= 1u;
v31 = (_EXP_SVM_DEVICE *)*(&WheapDeferredInternalLogsEventLock + 294);
if( (_UNKNOWN *)*(&WheapDeferredInternalLogsEventLock + 294) == (_UNKNOWN *)((char *)&WheapDeferredInternalLogsEventLock
+ 2352) )
goto LABEL_74;
do
{
v32 = v31;
v33 = v31;
Device = v31;
if( *((_DEVICE_OBJECT **)v31 + 2) == PhysicalDeviceObject )
break;
v31 = *(_EXP_SVM_DEVICE **)v31;
}
while( v31 != (_EXP_SVM_DEVICE *)((char *)&WheapDeferredInternalLogsEventLock + 2352) );
if( *((_DEVICE_OBJECT **)v33 + 2) != PhysicalDeviceObject )
{
v33 = 0i64;
Device = 0i64;
v32 = 0i64;
}
if( !v32 )
LABEL_74:
Interface = ExpPrepareNewSvmDevice(PhysicalDeviceObject, IommuContext, DeviceOut);
else
++v33[6];
if( (_InterlockedExchangeAdd64((_QWORD *)&WheapDeferredInternalLogsEventLock + 285, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)&WheapDeferredInternalLogsEventLock + 285);
LODWORD(v59) = 0;
v34 = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType((UINT64)&WheapDeferredInternalLogsEventLock + 2280) == 1 )
v35 = MmGetSessionIdEx(v34->Tcb.ApcState.Process);
else
v35 = -1;
--v34->Tcb.SpecialApcDisable;
v36 = ++v34->Tcb.AbAllocationRegionCount;
v37 = ((char)v34->Tcb.AbEntrySummary | (char)v34->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
while( 1 )
{
v17 = !_BitScanReverse((unsigned int *)&v38, v37);
if( v17 )
break;
v39 = &v34->Tcb.LockEntries[v38];
v37 &= ~(1 << v38);
if( (v39->AcquiredByte & 1) != 0
&& (v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (((unsigned __int64)&WheapDeferredInternalLogsEventLock
+ 2280) & 0x7FFFFFFFFFFFFFFCi64)
&& v39->LockState.SessionId == v35 )
{
v39->AcquiredByte &= ~1u;
if( v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
{
if( v39 )
{
v39->CrossThreadReleasableAndBusyByte |= 2u;
if( v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v39);
v40 = v39->BoostBitmap.AllFields & 0x1FFFF;
v41 = v39->BoostBitmap.AllFields & 0xFFFE0000;
v39->ThreadLocalFlags &= ~1u;
LODWORD(v59) = v40;
v39->BoostBitmap.AllFields = v41;
v39->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v42 = 1 << ((char)((_BYTE)v39 - LOBYTE(v34->Tcb.LockEntries)) / 96);
if( v36 == 1 )
v34->Tcb.AbEntrySummary |= v42;
else
_InterlockedOr8((volatile signed __int8 *)&v34->Tcb.AbOrphanedEntrySummary, v42);
goto LABEL_93;
}
break;
}
}
}
if( (*(&v34->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, v34, (char *)&WheapDeferredInternalLogsEventLock + 2280, (PVOID)v35, 0i64);
LABEL_93:
--v34->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v34->Tcb, (char *)&WheapDeferredInternalLogsEventLock + 2280, &v59);
v17 = v34->Tcb.SpecialApcDisable++ == -1;
if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v34->Tcb.ApcState.ApcListHead[0].Flink != &v34->Tcb.152 )
KiCheckForKernelApcDelivery();
v20 = Interface;
if( Interface >= 0 )
{
PoolWithTag = ExAllocatePoolWithTag(0x200ui64, 0x18ui64, 1682995269i64);
v6 = PoolWithTag;
if( PoolWithTag )
{
v44 = 0;
PoolWithTag[2] = Device;
v45 = KeGetCurrentIrql();
__writecr8(0xFui64);
KeAcquireInStackQueuedSpinLockAtDpcLevel(&Process->SvmLock, &LockHandle);
p_SvmProcessDeviceListHead = &Process->SvmProcessDeviceListHead;
Flink = Process->SvmProcessDeviceListHead.Flink;
if( Flink == &Process->SvmProcessDeviceListHead )
{
LABEL_105:
v48 = p_SvmProcessDeviceListHead->Flink;
if( p_SvmProcessDeviceListHead->Flink->Blink != p_SvmProcessDeviceListHead )
goto LABEL_112;
*v6 = v48;
v6[1] = p_SvmProcessDeviceListHead;
v48->Blink = (_LIST_ENTRY *)v6;
p_SvmProcessDeviceListHead->Flink = (_LIST_ENTRY *)v6;
}
else
{
while( (_DEVICE_OBJECT *)Flink[1].Flink[1].Flink != PhysicalDeviceObject )
{
Flink = Flink->Flink;
if( Flink == p_SvmProcessDeviceListHead )
goto LABEL_105;
}
v44 = 1;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(v45);
if( v44 )
{
ExFreePoolWithTag(v6, 0);
v20 = Interface;
v6 = 0i64;
}
else
{
MmEnableProcessSvm();
Interface = (*((__int64(__fastcall **)(VOID *, _QWORD))HalIommuDispatch + 4))(
IommuContext,
*((_QWORD *)Device + 15));
v20 = Interface;
if( Interface >= 0 )
{
v20 = (*((__int64(__fastcall **)(VOID *, unsigned __int64))HalIommuDispatch + 5))(
IommuContext,
Process->Pcb.DirectoryTableBase & 0xFFFFFFFFFFFFF000ui64);
Interface = v20;
}
}
}
else
{
v20 = -1073741670;
Interface = -1073741670;
}
}
LABEL_31:
((void(__fastcall *)(_EXP_SVM_DEVICE *))DeviceOut[3])(DeviceOut[1]);
if( v20 >= 0 )
{
*(_DWORD *)ReturnedAsid = DeviceAsid;
goto LABEL_114;
}
if( Device )
ExpSvmDereferenceDevice(Device);
if( !v6 )
goto LABEL_114;
v21 = KeGetCurrentIrql();
__writecr8(0xFui64);
KeAcquireInStackQueuedSpinLockAtDpcLevel(&Process->SvmLock, &LockHandle);
v22 = (VOID **)*v6;
v23 = (VOID ***)v6[1];
if( *((VOID ***)*v6 + 1) == v6 && *v23 == v6 )
{
*v23 = v22;
v22[1] = v23;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(v21);
ExFreePoolWithTag(v6, 0);
LABEL_114:
v5 = -1;
goto LABEL_115;
}
LABEL_112:
__fastfail(3u);
}
LABEL_14:
_interlockedbittestandset((volatile signed __int32 *)&v11->Tcb.116 + 1, 0x10u);
goto LABEL_21;
}
LABEL_115:
if( (_InterlockedExchangeAdd64(&Process->SvmProcessLock._bf_0, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock(&Process->SvmProcessLock);
v49 = (_ETHREAD *)KeGetCurrentThread();
LODWORD(v60) = 0;
if( MiGetSystemRegionType((UINT64)&Process->SvmProcessLock) == 1 )
v5 = MmGetSessionIdEx(v49->Tcb.ApcState.Process);
--v49->Tcb.SpecialApcDisable;
v50 = ++v49->Tcb.AbAllocationRegionCount;
v51 = ((char)v49->Tcb.AbEntrySummary | (char)v49->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
while( 1 )
{
v17 = !_BitScanReverse((unsigned int *)&v53, v51);
HIDWORD(v59) = v53;
if( v17 )
goto LABEL_126;
v52 = &v49->Tcb.LockEntries[v53];
v51 &= ~(1 << v53);
if( (v52->AcquiredByte & 1) != 0
&& (v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == ((unsigned __int64)&Process->SvmProcessLock & 0x7FFFFFFFFFFFFFFCi64)
&& v52->LockState.SessionId == v5 )
{
v52->AcquiredByte &= ~1u;
if( v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
break;
}
}
if( !v52 )
{
LABEL_126:
if( (*(&v49->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, v49, &Process->SvmProcessLock, (PVOID)v5, 0i64);
goto LABEL_133;
}
v52->CrossThreadReleasableAndBusyByte |= 2u;
if( v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v52);
v54 = v52->BoostBitmap.AllFields & 0x1FFFF;
v55 = v52->BoostBitmap.AllFields & 0xFFFE0000;
v52->ThreadLocalFlags &= ~1u;
LODWORD(v60) = v54;
v52->BoostBitmap.AllFields = v55;
v52->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v56 = v52 - v49->Tcb.LockEntries;
if( v50 == 1 )
v49->Tcb.AbEntrySummary |= 1 << v56;
else
_InterlockedOr8((volatile signed __int8 *)&v49->Tcb.AbOrphanedEntrySummary, 1 << v56);
LABEL_133:
--v49->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v49->Tcb, &Process->SvmProcessLock, &v60);
v17 = v49->Tcb.SpecialApcDisable++ == -1;
if( v17 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v49->Tcb.ApcState.ApcListHead[0].Flink != &v49->Tcb.152 )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)v64);
ExReleaseRundownProtection(&Process->RundownProtect);
return Interface;
}Referenced by:
No references.