KiSetFeatureBits
VOID __fastcall KiSetFeatureBits(_KPRCB *Prcb){
char CpuType;
unsigned __int8 CpuModel;
unsigned __int8 CpuVendor;
unsigned int ProcessorSignature;
__int64 v6;
unsigned __int8 v7;
unsigned __int32 v8;
__int64 v9;
void *v10;
__int64 v11;
unsigned __int32 v12;
unsigned __int64 v13;
char v14;
int v15;
unsigned __int64 v16;
unsigned __int8 v17;
unsigned int v18;
unsigned int v19;
__int64 v20;
int v21;
unsigned int v22;
__int64 v23;
char v24;
unsigned int v25;
char v26;
unsigned int v27;
unsigned __int8 v28;
unsigned int LogicalProcessorsPerCore;
INT8 IsHyperThreadingEnabled;
unsigned __int64 v31;
__int64 v32;
__int64 v33;
__int64 v34;
unsigned __int64 v35;
unsigned __int8 v36;
__int64 v37;
__int64 v38;
unsigned __int64 v39;
__int64 v40;
__int64 v41;
unsigned __int64 v42;
unsigned __int8 v43;
unsigned __int64 v44;
char v45;
unsigned __int8 v46;
unsigned __int8 CpuStepping;
__int64 v48;
int v49;
unsigned __int16 v50;
unsigned __int8 v51;
int v52;
__int64 v53;
unsigned int v54;
__int64 v55;
unsigned int v56;
unsigned int v57;
unsigned int v58;
__int32 v59;
unsigned __int64 v60;
unsigned __int64 v61;
unsigned __int8 v62;
unsigned int v63;
char v64;
unsigned __int32 v65;
bool v66;
unsigned __int32 v67;
unsigned __int32 v68;
__int32 v69;
__int16 v70;
unsigned __int32 v71;
__int16 v72;
CpuType = Prcb->CpuType;
CpuModel = Prcb->CpuModel;
CpuVendor = Prcb->CpuVendor;
v66 = (unsigned __int8)(CpuVendor - 1) <= 1u;
if( Prcb->Number )
{
ProcessorSignature = KiGetProcessorSignature(0i64, 0i64, 0i64, 0i64);
KiSetProcessorSignature((INT64)Prcb, ProcessorSignature);
goto LABEL_3;
}
if( CpuVendor == 2 )
{
if( CpuType != 6 )
goto LABEL_3;
KiLastExceptionFromBaseMSR = 477;
KiLastExceptionToBaseMSR = 478;
if( CpuModel <= 0x27u )
{
if( CpuModel < 0x26u && CpuModel != 15 && CpuModel != 23 )
{
if( CpuModel == 26 )
goto LABEL_89;
if( CpuModel != 28 && CpuModel != 29 )
{
if( CpuModel > 0x1Du && (CpuModel <= 0x1Fu || CpuModel == 37) )
goto LABEL_89;
goto LABEL_90;
}
}
}
else
{
if( CpuModel > 0x3Au )
{
if( CpuModel == 60 )
{
LABEL_89:
KiLastBranchFromBaseMSR = 1664;
KiLastBranchToBaseMSR = 1728;
goto LABEL_90;
}
if( CpuModel > 0x44u )
{
if( CpuModel <= 0x46u )
goto LABEL_89;
if( CpuModel == 77 )
goto LABEL_121;
}
LABEL_90:
if( KiLastBranchFromBaseMSR )
KiLastBranchTOSMSR = 457;
goto LABEL_3;
}
if( CpuModel == 58 || CpuModel == 42 )
goto LABEL_89;
if( CpuModel <= 0x2Bu )
goto LABEL_90;
if( CpuModel <= 0x2Fu )
goto LABEL_89;
if( CpuModel <= 0x34u || CpuModel > 0x37u )
goto LABEL_90;
}
LABEL_121:
KiLastBranchFromBaseMSR = 64;
KiLastBranchToBaseMSR = 96;
goto LABEL_90;
}
if( CpuVendor == 1 )
{
KiLastBranchFromBaseMSR = 475;
KiLastBranchToBaseMSR = 476;
KiLastExceptionFromBaseMSR = 477;
KiLastExceptionToBaseMSR = 478;
}
LABEL_3:
v6 = __cpuid(0, 0);
v69 = EDX(v6);
v65 = EAX(v6);
v7 = Prcb->CpuVendor;
if( v7 == 2 )
{
__writemsr(0x8Bu, 0i64);
v69 = EDX(__cpuid(1, 0));
LABEL_5:
Prcb->UpdateSignature.QuadPart = __readmsr(0x8Bu);
goto LABEL_6;
}
if( v7 == 1 )
{
v7 = 1;
goto LABEL_5;
}
LABEL_6:
v9 = __cpuid(1, 0);
v8 = EDX(v9);
v10 = (void *)v8;
v68 = v8;
v70 = ECX(v9);
v71 = EBX(v9);
v67 = EAX(__cpuid(0x80000000, 0));
v11 = __cpuid(-2147483647, 0);
v12 = EDX(v11);
v13 = (unsigned int)ECX(v11);
if( !Prcb->Number )
{
if( v7 == 1 )
{
v45 = Prcb->CpuType;
v46 = Prcb->CpuModel;
CpuStepping = Prcb->CpuStepping;
if( v45 == 15 && (v46 == 107 || v46 == 104) && CpuStepping == 1 )
{
KiCacheErrataMonitor |= 1ui64;
}
else if( v45 == 16
&& (!v46 && CpuStepping <= 2u
|| v46 == 2 && (CpuStepping <= 2u || CpuStepping == 10)
|| v46 == 4 && !CpuStepping) )
{
KiCacheErrataMonitor |= 2ui64;
}
}
if( !Prcb->Number )
{
v43 = Prcb->CpuVendor;
if( v43 == 1 )
{
if( Prcb->CpuType == 23 )
KiAccessBitErrata = 1;
}
else if( v43 == 2 && Prcb->CpuType == 6 )
{
if( (v44 = Prcb->CpuModel, (unsigned __int8)v44 <= 0x36u) && (v48 = 0x6000C010000000i64, _bittest64(&v48, v44))
|| (LOBYTE(v44) = v44 - 55, (unsigned __int8)v44 <= 0x16u)
&& (v49 = 4718593, _bittest(&v49, v44))
&& Prcb->CpuStepping <= 7u )
{
KiAccessBitErrata = 2;
}
}
}
}
KiDetectKvaLeakage((INT64)Prcb);
_m_prefetchw(Prcb);
v14 = 1;
if( Prcb->CpuVendor == 1 )
v12 |= 0x100000u;
Prcb->InitialApicId = HIBYTE(v71);
Prcb->CFlushSize = (v71 >> 5) & 0x7F8;
v15 = 0;
if( ((unsigned int)v10 & 0x789F3FD) != 126481405
|| (v12 & 0x800) == 0
|| (v12 & 0x100000) == 0
|| (v70 & 0x2000) == 0
|| (v13 & 1) == 0
|| (_DWORD)KiOpPrefetchPatchSkip )
{
if( !Prcb->Number )
KdInitSystem(0i64, KeLoaderBlock_0);
KeBugCheckEx(0x5Du, v10, (PVOID)v12, (PVOID)v13, (PVOID)(unsigned int)KiOpPrefetchPatchSkip);
}
v16 = Prcb->FeatureBits | 0x20113DFE;
if( (Prcb->FeatureBits & 0x400000000i64) != 0 )
__writemsr(0xC0000103, Prcb->GroupIndex | ((unsigned __int64)Prcb->Group << 8));
__writemsr(0x174u, 0i64);
__writemsr(0x176u, 0i64);
__writemsr(0x175u, 0i64);
if( (v12 & 0x2000000) != 0 )
__writemsr(0xC0000080, __readmsr(0xC0000080) | 0x4000);
Prcb->CoresPerPhysicalProcessor = 1;
Prcb->LogicalProcessorsPerCore = 1;
v17 = Prcb->CpuVendor;
if( (unsigned __int8)(v17 - 2) > 1u )
{
v27 = v67;
if( v17 == 1 && v67 >= 0x80000008 )
{
v50 = ECX(__cpuid(-2147483640, 0));
v51 = v50;
v52 = v50 >> 12;
if( !v52 )
_BitScanReverse((unsigned int *)&v52, 2 * v51 + 1);
Prcb->CoresPerPhysicalProcessor = 1 << v52;
if( v67 >= 0x8000001E && (v13 & 0x400000) != 0 )
{
v53 = __cpuid(-2147483618, 0);
v54 = (unsigned __int8)((unsigned __int16)EBX(v53) >> 8) + 1;
Prcb->LogicalProcessorsPerCore = v54;
Prcb->CoresPerPhysicalProcessor /= v54;
Prcb->InitialApicId = EAX(v53);
}
}
v18 = v65;
}
else
{
v18 = v65;
if( v65 >= 0x1F )
{
v55 = __cpuid(31, 0);
v19 = EDX(v55);
if( EBX(v55) )
v15 = 31;
}
else
{
v19 = v69;
}
if( v15 )
goto LABEL_27;
if( v65 >= 0xB )
{
v20 = __cpuid(11, 0);
v19 = EDX(v20);
if( EBX(v20) )
v15 = 11;
}
if( v15 )
{
LABEL_27:
Prcb->InitialApicId = v19;
v21 = 0;
v22 = 1;
do
{
v23 = __cpuid(v15, v21);
v24 = EAX(v23);
v72 = EBX(v23);
++v21;
v25 = (unsigned int)ECX(v23) >> 8;
if( v25 )
{
v26 = v24 & 0x1F;
if( v25 == 1 )
Prcb->LogicalProcessorsPerCore = 1 << v26;
else
v22 = 1 << v26;
}
}
while( v72 );
Prcb->CoresPerPhysicalProcessor = v22 / Prcb->LogicalProcessorsPerCore;
v18 = v65;
v14 = 1;
}
else
{
v56 = 1;
if( v65 >= 4 )
{
_BitScanReverse(&v57, 2 * ((unsigned int)EAX(__cpuid(4, 0)) >> 26) + 1);
v56 = 1 << v57;
Prcb->CoresPerPhysicalProcessor = 1 << v57;
}
if( (v68 & 0x10000000) != 0 )
{
_BitScanReverse(&v58, 2 * BYTE2(v71) - 1);
Prcb->LogicalProcessorsPerCore = (1 << v58) / v56;
}
}
v27 = v67;
}
v28 = Prcb->CpuVendor;
if( v28 == 1 )
{
v16 |= 0x200000ui64;
}
else if( v28 == 2 )
{
v16 |= 0x1000000ui64;
}
Prcb->LegacyCoresPerPhysicalProcessor = Prcb->CoresPerPhysicalProcessor;
Prcb->LegacyLogicalProcessorsPerCore = Prcb->LogicalProcessorsPerCore;
LogicalProcessorsPerCore = Prcb->LogicalProcessorsPerCore;
if( Prcb->Number )
{
IsHyperThreadingEnabled = HalIsHyperThreadingEnabled();
v14 = 1;
if( !IsHyperThreadingEnabled )
LogicalProcessorsPerCore *= Prcb->CoresPerPhysicalProcessor;
}
Prcb->ApicMask = -LogicalProcessorsPerCore;
if( (unsigned __int8)(Prcb->CpuVendor - 1) > 2u || v27 < 0x80000008 )
{
if( Prcb->CpuVendor == 1 )
KiMtrrMaxRangeShift = 40;
}
else
{
KiMtrrMaxRangeShift = EAX(__cpuid(-2147483640, 0));
}
KiMtrrMaskBase = ((1i64 << KiMtrrMaxRangeShift) - 1) & 0xFFFFFFFFFFFFF000ui64;
KiMtrrMaskMask = ((1i64 << KiMtrrMaxRangeShift) - 1) & 0xFFFFFFFFFFFFF000ui64;
v31 = __readcr4();
if( (v16 & 1) != 0 )
v31 |= 0x100000ui64;
v32 = v31 | 0x10000;
if( (v16 & 0x10000000) == 0 )
v32 = v31;
if( KeSmapEnabled )
v32 |= 0x200000ui64;
v33 = v32 | 0x800;
if( ((unsigned __int8)KeFeatureBits2 & 4) == 0 )
v33 = v32;
v34 = v33;
if( Prcb->Number && (v16 & 0x40000000000i64) != 0 && KiFlushPcid )
v34 = v33 | 0x20000;
__writecr4(v34);
if( KeSmapEnabled )
__stac();
if( (v34 & 0x20000) != 0 )
{
v35 = __readcr3();
__writecr3(v35 | 2);
}
v36 = Prcb->CpuVendor;
if( v36 == 2 && v18 >= 7 && (EBX(__cpuid(7, 0)) & 0x8000) != 0 && (EBX(__cpuid(16, 0)) & 2) != 0 )
v16 |= 0x100000000000ui64;
v37 = v16 | 0x20000;
if( !v66 )
v37 = v16;
v38 = v37;
if( v36 != 2 )
{
if( v36 == 1 )
{
if( (unsigned int)EAX(__cpuid(0x80000000, 0)) >= 0x8000000A )
{
v59 = EDX(__cpuid(-2147483638, 0));
v38 = v37 | 0x4000000;
if( (v59 & 1) == 0 )
v38 = v37;
if( (v59 & 0x20000) != 0 )
HvlSetHardwareMbecAvailable();
if( (v59 & 0x2000) != 0 )
HvlSetApicVirtualizationAvailable();
}
v60 = __readmsr(0xC0010114);
if( (v60 & 0x10) == 0 )
{
v38 |= 0x8000000ui64;
byte_140C50A87 |= v14;
}
}
goto LABEL_179;
}
if( (ECX(__cpuid(1, 0)) & 0x20) == 0 )
{
LABEL_179:
v41 = 0x10000000000i64;
goto LABEL_79;
}
if( (__readmsr(0x482u) & 0x8000000000000000ui64) == 0i64 )
{
v41 = 0x10000000000i64;
}
else
{
v39 = __readmsr(0x48Bu);
v40 = v37 | 0x4000000;
if( (v39 & 0x200000000i64) == 0 )
v40 = v37;
v37 = v40;
if( (v40 & 1) != 0 && (v39 & 0x40000000000000i64) != 0 )
HvlSetHardwareMbecAvailable();
v41 = 0x10000000000i64;
if( (v39 & 0x10000000000i64) != 0 )
HvlSetApicVirtualizationAvailable();
}
v42 = __readmsr(0x3Au);
v38 = v37 | 0x8000000;
if( (v42 & 5) != 5 )
v38 = v37;
if( (v42 & 4) != 0 )
byte_140C50A87 |= v14;
if( ((unsigned __int8)v42 & (unsigned __int8)v14) != 0 )
byte_140C50A87 |= 2u;
LABEL_79:
if( Prcb->CpuVendor == 2 && (EBX(__cpuid(7, 0)) & 4) != 0 )
{
v61 = __readmsr(0x3Au);
if( (v61 & 0x40001) == 262145 )
{
v62 = EAX(__cpuid(18, 0));
if( (v62 & (unsigned __int8)v14) != 0 )
{
v38 |= v41;
v63 = KUSER_SHARED_DATA.EnclaveFeatureMask[0] | 2;
KUSER_SHARED_DATA.EnclaveFeatureMask[0] |= 2u;
if( (v62 & 2) != 0 )
{
v38 |= 0x80000000000ui64;
KUSER_SHARED_DATA.EnclaveFeatureMask[0] = v63 | 4;
}
}
}
}
if( Prcb->CpuVendor == v14 )
{
v64 = Prcb->CpuType;
if( v64 > 15 && v64 != 17 && !HviIsAnyHypervisorPresent() )
__writemsr(0xC0011029, __readmsr(0xC0011029) | 2);
}
Prcb->FeatureBits = v38;
}Referenced by:
KiInitializeBootStructures