KiPerformGroupConfiguration
VOID __stdcall KiPerformGroupConfiguration(_LOADER_PARAMETER_BLOCK *LoaderBlock){
void *v1;
unsigned __int16 v2;
UINT8 *v3;
int v4;
unsigned __int16 v5;
int v6;
unsigned __int16 v7;
__int64 v8;
_DWORD *v9;
unsigned __int16 v10;
unsigned __int16 v11;
unsigned __int16 i;
int v13;
unsigned __int16 v14;
int ChannelInformation;
UINT64 v16;
char v17;
_QWORD *v18;
__int64 v19;
char v20;
PVOID v21;
UINT8 *v22;
__int64 v23;
__int64 v24;
__int64 v25;
__int64 v26;
__int64 v27;
_DWORD *v28;
int v29;
__int64 *v30;
__int64 v31;
__int64 v32;
unsigned __int64 v33;
UINT8 *v34;
__int64 v35;
__int64 v36;
UINT8 *v37;
__int64 v38;
int v39;
__m128 *v40;
unsigned __int16 v41;
__int64 j;
unsigned __int16 v43;
__int64 v44;
char v45;
__int64 v46;
unsigned int v47;
unsigned int v48;
__m128 *v49;
__int64 v50;
__int64 v51;
__int64 v52;
int v53;
unsigned __int16 v54;
unsigned __int16 v55;
__int64 v56;
unsigned __int16 v57;
__int64 v58;
__int64 v59;
__int64 *v60;
__int64 v61;
unsigned int v62;
bool v63;
__int64 v64;
unsigned __int16 v65;
__int16 v66;
__int64 v67;
__int64 *v68;
__int64 v69;
int v70;
int v71;
__int64 v72;
PVOID P;
UINT64 a4[3];
__m128 v75;
int v76[20];
__int64 result[64];
v1 = LoaderBlock;
P = LoaderBlock;
a4[1] = 0i64;
memset((INT64)result, 0i64);
v2 = KeNumberNodes;
v3 = &KeNodeBlock;
a4[0] = 0i64;
v4 = 0;
v71 = 0;
v5 = 0;
LODWORD(v72) = 0;
v6 = 0;
v7 = 0;
if( KeNumberNodes )
{
do
{
((void(__fastcall *)(_QWORD, int *))KiNumaQueryNodeCapacity[0])(v7, &v71);
v8 = *((_QWORD *)&KeNodeBlock + v7);
*(_BYTE *)(v8 + 180) = v71;
v4 += v71;
if( v71 )
++v5;
v9 = (_DWORD *)(v8 + 168);
if( KiNumaQueryProximityId )
{
((void(__fastcall *)(_QWORD, _DWORD *, __int64 *))KiNumaQueryProximityId)(v7, v9, &v72);
((void(__fastcall *)(_QWORD, __int64))KiNumaQueryProximityNode)(
(unsigned int)v72,
*((_QWORD *)&KeNodeBlock + v7) + 148i64);
if( *(_DWORD *)(*((_QWORD *)&KeNodeBlock + v7) + 168i64) == (_DWORD)v72 )
++v6;
}
else
{
*v9 = 0;
v6 = 1;
*(_WORD *)(v8 + 148) = *(_WORD *)(v8 + 146);
}
++v7;
v2 = KeNumberNodes;
}
while( v7 < (unsigned __int16)KeNumberNodes );
v1 = P;
HIDWORD(a4[0]) = v4;
}
if( v2 > 1u )
{
*(_QWORD *)KeNodeDistance = ExAllocatePoolWithTag(NonPagedPoolNx, 4 * v2 * (unsigned int)v2, 0x2020654Bui64);
if( !*(_QWORD *)KeNodeDistance )
KeBugCheckEx(0x32u, 0xFFFFFFFFC000009Aui64, 0i64, 0i64, 0i64);
}
v10 = KeNumberNodes;
v11 = 0;
if( KeNumberNodes )
{
do
{
for( i = 0;
i < v10;
*(_DWORD *)(*(_QWORD *)KeNodeDistance + 4i64 * (v13 + v11 * (unsigned __int16)KeNumberNodes)) = a4[0] )
{
((void(__fastcall *)(_QWORD, _QWORD, UINT64 *))KiNumaQueryNodeDistance[0])(v11, i, a4);
v10 = KeNumberNodes;
v13 = i++;
}
++v11;
}
while( v11 < v10 );
v1 = P;
v3 = &KeNodeBlock;
}
P = 0i64;
v14 = 0;
if( v10 )
{
do
{
if( *(_WORD *)(*((_QWORD *)&KeNodeBlock + v14) + 146i64) == *(_WORD *)(*((_QWORD *)&KeNodeBlock + v14) + 148i64) )
{
ChannelInformation = MmGetChannelInformation(0, v14, (UINT8 **)&P, &a4[1]);
if( ChannelInformation < 0 )
KeBugCheckEx(0x32u, ChannelInformation, 0i64, 0i64, 0i64);
v16 = 0i64;
v17 = 1;
if( a4[1] / 0x28 )
{
v18 = (char *)P + 8;
while( !*v18 )
{
++v16;
v18 += 5;
if( v16 >= a4[1] / 0x28 )
goto LABEL_22;
}
v17 = 0;
}
LABEL_22:
v19 = *((_QWORD *)&KeNodeBlock + v14);
v20 = (16 * v17) | *(_BYTE *)(v19 + 181) & 0xEF;
v21 = P;
*(_BYTE *)(v19 + 181) = v20;
ExFreePoolWithTag(v21, 0);
P = 0i64;
}
++v14;
}
while( v14 < (unsigned __int16)KeNumberNodes );
if( KeNumberNodes )
{
v22 = &KeNodeBlock;
v23 = (unsigned __int16)KeNumberNodes;
do
{
v24 = *(unsigned __int16 *)(*(_QWORD *)v22 + 148i64);
if( *(_WORD *)(*(_QWORD *)v22 + 146i64) != (_WORD)v24 )
*(_BYTE *)(*(_QWORD *)v22 + 181i64) ^= (*(_BYTE *)(*(_QWORD *)v22 + 181i64) ^ *(_BYTE *)(*((_QWORD *)&KeNodeBlock + v24)
+ 181i64)) & 0x10;
v22 += 8;
--v23;
}
while( v23 );
}
}
*(_OWORD *)&a4[1] = 0i64;
if( (_BYTE)HvlHypervisorConnected )
{
v29 = KeRootProcSpecified;
if( !KeRootProcSpecified && KeRootProcNumaNodeLpsSpecified )
{
v30 = KeRootProcNumaNodeLps;
v31 = (unsigned int)(KeRootProcSpecified + 64);
do
{
v32 = *v30;
v33 = *v30++;
v29 += (unsigned int)((0x101010101010101i64
* ((((v32 - ((v33 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v32 - ((v33 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)
+ ((((v32 - ((v33 >> 1) & 0x5555555555555555i64)) & 0x3333333333333333i64)
+ (((v32 - ((v33 >> 1) & 0x5555555555555555i64)) >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24;
--v31;
}
while( v31 );
}
if( (HvlpRootFlags & 1) != 0 && (unsigned int)(v29 - 1) <= 0x3F && !KeDynamicPartitioningSupported )
goto LABEL_35;
if( (HvlpFlags & 0x80u) == 0i64 )
{
HviGetImplementationLimits((INT32 *)&a4[1]);
if( LODWORD(a4[1]) != -1 )
goto LABEL_35;
}
}
v25 = *((_QWORD *)v1 + 30);
v26 = 20i64;
LOWORD(v70) = 0;
v27 = 0xFFFFi64;
v28 = *(_DWORD **)(v25 + 304);
if( v28 && v6 == *v28 )
{
if( KeNumberNodes )
{
v34 = &KeNodeBlock;
v35 = (unsigned __int16)KeNumberNodes;
do
{
v36 = *(_QWORD *)v34;
v34 += 8;
*(_WORD *)(v36 + 144) = -1;
*(_BYTE *)(v36 + 181) &= ~2u;
--v35;
}
while( v35 );
}
if( v6 )
{
while( 1 )
{
--v6;
if( (unsigned int)((__int64(__fastcall *)(_QWORD, int *, __int64))KiNumaQueryProximityNode)(
(unsigned int)v28[1],
&v70,
v27) )
break;
v28 += 2;
if( *v28 >= 0x14u && *v28 != 0xFFFF )
break;
if( KeNumberNodes )
{
v37 = &KeNodeBlock;
v27 = (unsigned __int16)KeNumberNodes;
do
{
v38 = *(_QWORD *)v37;
if( *(_WORD *)(*(_QWORD *)v37 + 148i64) == (_WORD)v70 )
{
*(_WORD *)(v38 + 144) = *(_WORD *)v28;
*(_BYTE *)(v38 + 181) |= 2u;
}
v37 += 8;
--v27;
}
while( v27 );
}
if( !v6 )
goto LABEL_68;
}
}
else
{
LABEL_68:
if( *(_WORD *)(*(_QWORD *)&KeNodeBlock + 144i64) != 0xFFFF )
{
v39 = KiMaximumGroupSize;
v40 = &v75;
v41 = KeNumberNodes;
for( j = 20i64; j; --j )
{
v40->m128_i32[0] = v39;
v40 = (__m128 *)((char *)v40 + 4);
}
v43 = 0;
if( !v41 )
{
LABEL_79:
KiMaximumGroups = 0;
v49 = &v75;
do
{
if( v49->m128_i32[0] < (unsigned int)KiMaximumGroupSize )
++KiMaximumGroups;
v49 = (__m128 *)((char *)v49 + 4);
--v26;
}
while( v26 );
if( KeNumberNodes )
{
v50 = (unsigned __int16)KeNumberNodes;
do
{
v51 = *(_QWORD *)v3;
v3 += 8;
*(_BYTE *)(v51 + 181) |= 8u;
--v50;
}
while( v50 );
}
return;
}
while( 1 )
{
v44 = *((_QWORD *)&KeNodeBlock + v43);
v45 = *(_BYTE *)(v44 + 181);
if( (v45 & 2) == 0 )
break;
v46 = *(unsigned __int16 *)(v44 + 144);
if( (_WORD)v46 == 0xFFFF )
{
*(_BYTE *)(v44 + 181) = v45 & 0xFD;
}
else
{
v47 = *(unsigned __int8 *)(v44 + 180);
v48 = v75.m128_u32[v46];
if( v48 < v47 )
break;
v75.m128_i32[v46] = v48 - v47;
}
if( ++v43 >= v41 )
goto LABEL_79;
}
}
}
}
if( strstr(*((CHAR **)v1 + 27), "MAXGROUP=OFF") )
{
KiMaximizeGroupsCreated = 0;
}
else if( strstr(*((CHAR **)v1 + 27), "MAXGROUP") )
{
KiMaximizeGroupsCreated = 1;
}
if( v5 == 1 || !KiMaximizeGroupsCreated && HIDWORD(a4[0]) <= KiMaximumGroupSize )
{
LABEL_35:
KiAssignAllNodesToGroup0();
return;
}
v52 = (unsigned __int16)KeNumberNodes;
v53 = 0;
v54 = 0;
if( KeNumberNodes )
{
do
{
v55 = 0;
while( v54 == v55 || *(_DWORD *)(*(_QWORD *)KeNodeDistance + 4i64 * (v55 + v54 * (int)v52)) == 0xFFFF )
{
if( ++v55 >= (unsigned __int16)v52 )
goto LABEL_95;
}
v56 = *((_QWORD *)&KeNodeBlock + v54);
*(_BYTE *)(v56 + 181) |= 8u;
v53 += *(unsigned __int8 *)(v56 + 180);
LABEL_95:
++v54;
}
while( v54 < (unsigned __int16)v52 );
memmove((UINT8 *)result, &KeNodeBlock, 8 * v52);
}
if( (int)v52 - 1 > 0 )
{
v57 = 1;
do
{
if( v57 < (unsigned __int16)KeNumberNodes )
{
v58 = (unsigned __int16)(v57 - 1);
v59 = (unsigned __int16)(KeNumberNodes - v57);
v60 = &result[v57];
do
{
v61 = result[v58];
if( *(_BYTE *)(v61 + 180) < *(_BYTE *)(*v60 + 180) )
{
result[v58] = *v60;
*v60 = v61;
}
++v60;
--v59;
}
while( v59 );
}
++v57;
}
while( (unsigned __int16)(v57 - 1) < (int)v52 - 1 );
}
if( !v53 )
{
LOWORD(v62) = 1;
LABEL_112:
v63 = (_WORD)v62 == 20;
goto LABEL_113;
}
if( KiMaximizeGroupsCreated )
LOWORD(v62) = v5;
else
v62 = (v53 + KiMaximumGroupSize - 1) / (unsigned int)KiMaximumGroupSize;
v63 = (_WORD)v62 == 20;
if( (unsigned __int16)v62 > 0x14u )
{
LOWORD(v62) = 20;
goto LABEL_112;
}
do
{
LABEL_113:
if( KiAssignFixedNodes(result, v5, v62, v63, v76, &v75) )
break;
LOWORD(v62) = v62 + 1;
v63 = (_WORD)v62 == 20;
}
while( (unsigned __int16)v62 <= 0x14u );
KiShuffleAssignedNodes((UINT64)result, v5);
v65 = KiAssignAdjustableNodes(result, v5, v64, (__int64)v76);
if( (unsigned __int16)v62 > v65 )
v65 = v62;
KiMaximumGroups = v65;
v66 = *(_WORD *)(*(_QWORD *)&KeNodeBlock + 144i64);
if( v5 < (unsigned __int16)KeNumberNodes )
{
v67 = (unsigned __int16)(KeNumberNodes - v5);
v68 = &result[v5];
do
{
v69 = *v68++;
*(_WORD *)(v69 + 144) = v66;
*(_BYTE *)(v69 + 181) |= 2u;
--v67;
}
while( v67 );
}
}Referenced by:
KePerformGroupConfiguration