KiIpiSendRequest
VOID __stdcall KiIpiSendRequest(
_KPRCB *Prcb,
_IPI_TYPE IpiType,
_KAFFINITY_EX *TargetSet,
UINT64 Parameter,
UINT64 RequestType,
UINT64 a6){
_IPI_TYPE v7;
_KPRCB *v8;
_KAFFINITY_EX *p_KeIpiSendAffinity;
_KAFFINITY_EX *p_KeIpiSendIpiSet;
unsigned __int16 v11;
__int64 v12;
UINT64 v13;
UINT64 v14;
int v15;
UINT64 v16;
int v17;
int v18;
int v19;
unsigned int v20;
__int64 v21;
__int64 v22;
unsigned __int64 v23;
_QWORD *v24;
int v25;
unsigned __int64 v26;
__int64 v27;
__int64 v28;
signed __int64 *v29;
signed __int64 v30;
signed __int64 v31;
unsigned int v32;
unsigned int v33;
__int64 v34;
char *v35;
__int64 v36;
__int64 v37;
int v38;
int v39;
int v40;
int v41;
unsigned int Number;
__int64 v43;
unsigned __int16 v44;
unsigned __int64 v47;
_LARGE_INTEGER TimeStamp[2];
__int128 v49;
__int128 v50;
v7 = IpiType;
v8 = Prcb;
*(_OWORD *)&TimeStamp[0].anonymous_0.LowPart = 0i64;
v49 = 0i64;
p_KeIpiSendAffinity = &Prcb->StaticAffinity.KeIpiSendAffinity;
p_KeIpiSendIpiSet = &Prcb->StaticAffinity.KeIpiSendIpiSet;
if( IpiType )
{
KeCopyAffinityEx(&Prcb->StaticAffinity.KeIpiSendAffinity, &KeActiveProcessors);
if( v7 == IpiAllButSelf )
KeRemoveProcessorAffinityEx(&v8->StaticAffinity.KeIpiSendAffinity.Count, v8->Number);
v13 = RequestType;
if( (RequestType & 0x80000000) != 0 )
{
LODWORD(v13) = RequestType & 0x7FFFFFFF;
if( !KeIsEmptyAffinityEx(&KeSleepingProcessors.Count) )
{
v7 = IpiAffinity;
KeSubtractAffinityEx(
&v8->StaticAffinity.KeIpiSendAffinity.Count,
(INT8 *)&KeSleepingProcessors,
(INT8 *)&v8->StaticAffinity.KeIpiSendAffinity);
}
}
}
else
{
p_KeIpiSendAffinity->Count = TargetSet->Count;
Prcb->StaticAffinity.KeIpiSendAffinity.Size = TargetSet->Size;
v11 = 0;
for( Prcb->StaticAffinity.KeIpiSendAffinity.Reserved = 0;
v11 < TargetSet->Count;
p_KeIpiSendAffinity->Bitmap[v12] = TargetSet->Bitmap[v12] )
{
v12 = v11++;
}
v13 = RequestType;
}
v14 = Parameter;
v15 = (unsigned __int16)KeNumberNodes;
v8->TargetCount = (unsigned __int16)KeNumberNodes;
v16 = v13 & 0xF | (v14 << 7);
Number = v8->Number;
v8->PacketBarrier = 1;
*(_QWORD *)&p_KeIpiSendIpiSet->Count = 1310721i64;
memset(v8->StaticAffinity.KeIpiSendIpiSet.Bitmap, 0i64, sizeof(v8->StaticAffinity.KeIpiSendIpiSet.Bitmap));
v41 = 0;
v17 = 0;
v40 = 0;
v18 = 0;
v39 = 0;
v19 = 0;
v20 = 0;
if( v15 )
{
do
{
v50 = 0i64;
v21 = KeNodeBlock[v20];
v22 = *(unsigned __int16 *)(v21 + 144);
if( p_KeIpiSendAffinity->Count > (unsigned __int16)v22
&& (v23 = *(_QWORD *)(v21 + 136) & p_KeIpiSendAffinity->Bitmap[v22], (v47 = v23) != 0) )
{
v24 = 0i64;
v44 = *(_WORD *)(v21 + 144);
v25 = v44;
while( v23 )
{
LABEL_10:
v25 = v44;
_BitScanForward64(&v26, v23);
v43 = v23 & ~(1i64 << v26);
v27 = (unsigned int)KiProcessorNumberToIndexMappingTable[64 * v44 + (unsigned __int8)v26];
v28 = (__int64)*(&KiProcessorBlock + v27);
_m_prefetchw((const void *)(v28 + 35904));
v29 = (signed __int64 *)(v28 + ((Number + 699i64) << 6));
_m_prefetchw(v29);
if( !v24 )
{
v24 = v29 + 7;
*((_DWORD *)v29 + 14) = (unsigned int)((0x101010101010101i64
* ((((v47 - ((v47 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v47 - ((v47 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((v47 - ((v47 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v47 - ((v47 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24;
}
v29[6] = (signed __int64)v24;
if( v13 == 5 )
{
*((_OWORD *)v29 + 1) = *(_OWORD *)Parameter;
*((_OWORD *)v29 + 2) = *(_OWORD *)(Parameter + 16);
}
v29[1] = v16;
v30 = *(_QWORD *)(v28 + 35904);
do
{
v31 = v30;
*v29 = v30;
v30 = _InterlockedCompareExchange64((volatile signed __int64 *)(v28 + 35904), (signed __int64)v29, v30);
}
while( v30 != v31 );
if( v30 )
{
v39 = 1;
}
else
{
v32 = KiProcessorIndexToNumberMappingTable[v27];
v33 = v32 & 0x3F;
v34 = v32 >> 6;
v40 = 1;
if( p_KeIpiSendIpiSet->Count <= (unsigned int)v34 )
p_KeIpiSendIpiSet->Count = v34 + 1;
v35 = (char *)p_KeIpiSendIpiSet + 8 * v34;
v36 = *((_QWORD *)v35 + 1);
_bittestandset64(&v36, v33);
*((_QWORD *)v35 + 1) = v36;
}
v37 = *(_QWORD *)(v28 + 33976);
if( v37 )
_InterlockedIncrement((volatile signed __int32 *)(v37 + 32));
v23 = v43;
}
while( ++v44 < (unsigned int)(v25 + 1) )
{
v23 = *(_QWORD *)(8i64 * v44 + 8);
if( v23 )
goto LABEL_10;
}
v19 = v41;
}
else
{
v41 = ++v19;
}
++v20;
}
while( v20 < (unsigned __int16)KeNumberNodes );
v8 = Prcb;
if( v19 && _InterlockedExchangeAdd(&Prcb->TargetCount, -v19) == v19 )
{
Prcb->PacketBarrier = 0;
return;
}
v17 = v40;
v18 = v39;
}
if( v13 != 5 && v18 )
{
if( v17 )
{
++v8->SynchCounters.IpiSendRequestRoutineCount;
KiIpiEnlightenedGuestPriorityKick((INT64)p_KeIpiSendIpiSet);
HalRequestIpi(IpiAffinity, p_KeIpiSendIpiSet);
}
}
else
{
if( (unsigned int)(v7 - 1) <= 1 )
++v8->SynchCounters.IpiSendRequestBroadcastCount;
else
++v8->SynchCounters.IpiSendRequestRoutineCount;
KiIpiEnlightenedGuestPriorityKick((INT64)p_KeIpiSendAffinity);
HalRequestIpiSpecifyVector(v7, p_KeIpiSendAffinity, 0xE1ui64);
if( v38 < 0 )
KeBugCheckEx(0x5Cu, (PVOID)0x201, (PVOID)Controller, (PVOID)v38, (PVOID)(int)v7);
}
}Referenced by:
KeFlushMultipleRangeTb
KiIpiSendPacket
KiIpiSendRequestEx
KxFlushEntireTb