Skip to content

Commit f67b2e6

Browse files
committed
added xeon_thread_mismatch technique
1 parent 319eb35 commit f67b2e6

2 files changed

Lines changed: 199 additions & 19 deletions

File tree

src/cli.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ int main(int argc, char* argv[]) {
238238
checker(VM::UPTIME, "uptime");
239239
checker(VM::ODD_CPU_THREADS, "unusual thread count");
240240
checker(VM::INTEL_THREAD_MISMATCH, "Intel thread count mismatch");
241+
checker(VM::XEON_THREAD_MISMATCH, "Intel Xeon thread count mismatch");
241242

242243
std::printf("\n");
243244

src/vmaware.hpp

Lines changed: 198 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ struct VM {
348348
UPTIME,
349349
ODD_CPU_THREADS,
350350
INTEL_THREAD_MISMATCH,
351-
INTEL_XEON_THREAD_MISMATCH,
351+
XEON_THREAD_MISMATCH,
352352
EXTREME,
353353
NO_MEMO,
354354
WIN_HYPERV_DEFAULT,
@@ -589,20 +589,22 @@ struct VM {
589589
#endif
590590
}
591591

592-
[[nodiscard]] static std::string get_model() {
592+
struct model_struct {
593+
bool found;
594+
bool is_xeon;
595+
bool is_i_series;
596+
std::string string;
597+
};
598+
599+
[[nodiscard]] static model_struct get_model() {
593600
const std::string brand = get_brand();
594601

595602
constexpr const char* intel_i_series_regex = "i[0-9]-[A-Z0-9]{1,7}";
596603
constexpr const char* intel_xeon_series_regex = "[DEW]-[A-Z0-9]{1,7}";
597604

598-
constexpr std::array<const char*, 2> regex_templates {{
599-
intel_i_series_regex,
600-
intel_xeon_series_regex
601-
}};
602-
603605
std::string match_str = "";
604606

605-
for (const auto regex : regex_templates) {
607+
auto match = [&](const char* regex) -> bool {
606608
std::regex pattern(regex);
607609

608610
auto words_begin = std::sregex_iterator(brand.begin(), brand.end(), pattern);
@@ -614,11 +616,32 @@ struct VM {
614616
}
615617

616618
if (!match_str.empty()) {
617-
return match_str;
619+
return true;
620+
}
621+
622+
return false;
623+
};
624+
625+
bool found = false;
626+
bool is_xeon = false;
627+
bool is_i_series = false;
628+
std::string string = "";
629+
630+
if (cpu::is_intel()) {
631+
if (match(intel_i_series_regex)) {
632+
found = true;
633+
is_i_series = true;
634+
string = match_str;
635+
} else if (match(intel_xeon_series_regex)) {
636+
found = true;
637+
is_xeon = true;
638+
string = match_str;
618639
}
619640
}
620641

621-
return "";
642+
// no AMD (for now)
643+
644+
return model_struct{ found, is_xeon, is_i_series, string };
622645
};
623646

624647
#if (CPP >= 17)
@@ -4901,7 +4924,6 @@ struct VM {
49014924
IDTR idtrStruct;
49024925
__sidt(&idtrStruct);
49034926
std::memcpy(idtr, &idtrStruct, sizeof(IDTR));
4904-
*/
49054927
#else
49064928
return false;
49074929
#endif
@@ -5877,7 +5899,7 @@ struct VM {
58775899
/**
58785900
* @brief Check for CPUs that don't match their thread count
58795901
* @category All, x86
5880-
* @links https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
5902+
* @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
58815903
*/
58825904
[[nodiscard]] static bool intel_thread_mismatch() try {
58835905
if (core::disabled(INTEL_THREAD_MISMATCH)) {
@@ -5891,15 +5913,19 @@ struct VM {
58915913
return false;
58925914
}
58935915

5894-
const std::string model = cpu::get_model();
5916+
const cpu::model_struct model = cpu::get_model();
58955917

5896-
debug("INTEL_THREAD_MISMATCH: CPU model = ", model);
5918+
if (!model.found) {
5919+
return false;
5920+
}
58975921

5898-
if (model.empty()) {
5922+
if (!model.is_i_series) {
58995923
return false;
59005924
}
59015925

5902-
std::unordered_map<std::string, u8> thread_database = {
5926+
debug("INTEL_THREAD_MISMATCH: CPU model = ", model.string);
5927+
5928+
const std::unordered_map<std::string, u8> thread_database = {
59035929
// i3 series
59045930
{ "i3-1000G1", 4 },
59055931
{ "i3-1000G4", 4 },
@@ -6856,11 +6882,11 @@ struct VM {
68566882
};
68576883

68586884
// basically means "if there's 0 matches in the database, return false"
6859-
if (thread_database.count(model) == 0) {
6885+
if (thread_database.count(model.string) == 0) {
68606886
return false;
68616887
}
68626888

6863-
const u8 threads = thread_database.at(model);
6889+
const u8 threads = thread_database.at(model.string);
68646890

68656891
debug("INTEL_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
68666892

@@ -6873,6 +6899,158 @@ struct VM {
68736899
}
68746900

68756901

6902+
/**
6903+
* @brief Check for Intel Xeon CPUs that don't match their thread count
6904+
* @category All, x86
6905+
* @link https://en.wikipedia.org/wiki/List_of_Intel_Core_processors
6906+
*/
6907+
[[nodiscard]] static bool xeon_thread_mismatch() try {
6908+
if (core::disabled(XEON_THREAD_MISMATCH)) {
6909+
return false;
6910+
}
6911+
6912+
#if (!x86)
6913+
return false;
6914+
#else
6915+
if (!cpu::is_intel()) {
6916+
return false;
6917+
}
6918+
6919+
const cpu::model_struct model = cpu::get_model();
6920+
6921+
if (!model.found) {
6922+
return false;
6923+
}
6924+
6925+
if (!model.is_i_series) {
6926+
return false;
6927+
}
6928+
6929+
debug("XEON_THREAD_MISMATCH: CPU model = ", model.string);
6930+
6931+
const std::unordered_map<std::string, u8> xeon_thread_database = {
6932+
// Xeon D
6933+
{ "D-1518", 8 },
6934+
{ "D-1520", 8 },
6935+
{ "D-1521", 8 },
6936+
{ "D-1527", 8 },
6937+
{ "D-1528", 12 },
6938+
{ "D-1529", 8 },
6939+
{ "D-1531", 12 },
6940+
{ "D-1537", 16 },
6941+
{ "D-1539", 16 },
6942+
{ "D-1540", 16 },
6943+
{ "D-1541", 16 },
6944+
{ "D-1548", 16 },
6945+
{ "D-1557", 24 },
6946+
{ "D-1559", 24 },
6947+
{ "D-1567", 24 },
6948+
{ "D-1571", 32 },
6949+
{ "D-1577", 32 },
6950+
{ "D-1581", 32 },
6951+
{ "D-1587", 32 },
6952+
{ "D-1513N", 8 },
6953+
{ "D-1523N", 8 },
6954+
{ "D-1533N", 12 },
6955+
{ "D-1543N", 16 },
6956+
{ "D-1553N", 16 },
6957+
{ "D-1602", 4 },
6958+
{ "D-1612", 8 },
6959+
{ "D-1622", 8 },
6960+
{ "D-1627", 8 },
6961+
{ "D-1632", 16 },
6962+
{ "D-1637", 12 },
6963+
{ "D-1623N", 8 },
6964+
{ "D-1633N", 12 },
6965+
{ "D-1649N", 16 },
6966+
{ "D-1653N", 16 },
6967+
{ "D-2141I", 16 },
6968+
{ "D-2161I", 24 },
6969+
{ "D-2191", 36 },
6970+
{ "D-2123IT", 8 },
6971+
{ "D-2142IT", 16 },
6972+
{ "D-2143IT", 16 },
6973+
{ "D-2163IT", 24 },
6974+
{ "D-2173IT", 28 },
6975+
{ "D-2183IT", 32 },
6976+
{ "D-2145NT", 16 },
6977+
{ "D-2146NT", 16 },
6978+
{ "D-2166NT", 24 },
6979+
{ "D-2177NT", 28 },
6980+
{ "D-2187NT", 32 },
6981+
6982+
// Xeon E
6983+
{ "E-2104G", 4 },
6984+
{ "E-2124", 4 },
6985+
{ "E-2124G", 4 },
6986+
{ "E-2126G", 6 },
6987+
{ "E-2134", 8 },
6988+
{ "E-2136", 12 },
6989+
{ "E-2144G", 8 },
6990+
{ "E-2146G", 12 },
6991+
{ "E-2174G", 8 },
6992+
{ "E-2176G", 12 },
6993+
{ "E-2186G", 12 },
6994+
{ "E-2176M", 12 },
6995+
{ "E-2186M", 12 },
6996+
{ "E-2224", 4 },
6997+
{ "E-2224G", 4 },
6998+
{ "E-2226G", 6 },
6999+
{ "E-2234", 8 },
7000+
{ "E-2236", 12 },
7001+
{ "E-2244G", 8 },
7002+
{ "E-2246G", 12 },
7003+
{ "E-2274G", 8 },
7004+
{ "E-2276G", 12 },
7005+
{ "E-2278G", 16 },
7006+
{ "E-2286G", 12 },
7007+
{ "E-2288G", 16 },
7008+
{ "E-2276M", 12 },
7009+
{ "E-2286M", 16 },
7010+
7011+
// Xeon W
7012+
{ "W-2102", 4 },
7013+
{ "W-2104", 4 },
7014+
{ "W-2123", 8 },
7015+
{ "W-2125", 8 },
7016+
{ "W-2133", 12 },
7017+
{ "W-2135", 12 },
7018+
{ "W-2140B", 16 },
7019+
{ "W-2145", 16 },
7020+
{ "W-2150B", 20 },
7021+
{ "W-2155", 20 },
7022+
{ "W-2170B", 28 },
7023+
{ "W-2175", 28 },
7024+
{ "W-2191B", 36 },
7025+
{ "W-2195", 36 },
7026+
{ "W-3175X", 56 },
7027+
{ "W-3223", 16 },
7028+
{ "W-3225", 16 },
7029+
{ "W-3235", 24 },
7030+
{ "W-3245", 32 },
7031+
{ "W-3245M", 32 },
7032+
{ "W-3265", 48 },
7033+
{ "W-3265M", 48 },
7034+
{ "W-3275", 56 },
7035+
{ "W-3275M", 56 }
7036+
};
7037+
7038+
if (xeon_thread_database.count(model.string) == 0) {
7039+
return false;
7040+
}
7041+
7042+
const u8 threads = xeon_thread_database.at(model.string);
7043+
7044+
debug("XEON_THREAD_MISMATCH: thread in database = ", static_cast<u32>(threads));
7045+
7046+
return (std::thread::hardware_concurrency() != threads);
7047+
#endif
7048+
}
7049+
catch (...) {
7050+
debug("INTEL_THREAD_MISMATCH: catched error, returned false");
7051+
return false;
7052+
}
7053+
68767054
struct core {
68777055
MSVC_DISABLE_WARNING(PADDING)
68787056
struct technique {
@@ -7462,7 +7640,8 @@ const std::map<VM::u8, VM::core::technique> VM::core::table = {
74627640
{ VM::MUTEX, { 85, VM::mutex }},
74637641
{ VM::UPTIME, { 10, VM::uptime }},
74647642
{ VM::ODD_CPU_THREADS, { 80, VM::odd_cpu_threads }},
7465-
{ VM::INTEL_THREAD_MISMATCH, { 70, VM::intel_thread_mismatch }}
7643+
{ VM::INTEL_THREAD_MISMATCH, { 85, VM::intel_thread_mismatch }},
7644+
{ VM::XEON_THREAD_MISMATCH, { 85, VM::xeon_thread_mismatch }}
74667645

74677646
// __TABLE_LABEL, add your technique above
74687647
// { VM::FUNCTION, { POINTS, FUNCTION_POINTER }}

0 commit comments

Comments
 (0)