@@ -3862,8 +3862,8 @@ struct VM {
38623862 }
38633863
38643864 #if (WINDOWS)
3865- const std::string& brand = cpu::get_brand();
3866- if (brand.find( "Virtual CPU") != std::string::npos ) {
3865+ const char* brand = cpu::get_brand();
3866+ if (brand && strstr(brand, "Virtual CPU")) {
38673867 return true;
38683868 }
38693869 #endif
@@ -4468,7 +4468,7 @@ struct VM {
44684468 #if (x86)
44694469 i32 regs[4];
44704470 cpu::cpuid(regs, 1);
4471- return (regs[2] & (1 << 20)) != 0; // ECX Bit 20: SSE4.2
4471+ return (regs[2] & (1 << 20)) != 0;
44724472 #else
44734473 return false;
44744474 #endif
@@ -4498,7 +4498,7 @@ struct VM {
44984498 return crc;
44994499 }
45004500
4501- // Native /SSE4.2 hardware assisted or software CRC32C of a single byte
4501+ // native /SSE4.2 hardware assisted or software CRC32C of a single byte
45024502 #if (x86 && (GCC || CLANG))
45034503 __attribute__((__target__("sse4.2")))
45044504 #endif
@@ -4721,7 +4721,7 @@ struct VM {
47214721 };
47224722
47234723 static constexpr rule merge_rules[] = {
4724- // Double merges
4724+ // double merges
47254725 { brand_enum::VPC, brand_enum::HYPERV, brand_enum::INVALID, brand_enum::HYPERV_VPC },
47264726
47274727 { brand_enum::AZURE_HYPERV, brand_enum::HYPERV, brand_enum::INVALID, brand_enum::AZURE_HYPERV },
@@ -4746,7 +4746,7 @@ struct VM {
47464746 { brand_enum::HYPERV_VPC, brand_enum::QEMU_KVM_HYPERV, brand_enum::INVALID, brand_enum::QEMU_KVM_HYPERV },
47474747 { brand_enum::HYPERV, brand_enum::QEMU_KVM_HYPERV, brand_enum::INVALID, brand_enum::QEMU_KVM_HYPERV },
47484748
4749- // Triple merge
4749+ // triple merge
47504750 { brand_enum::QEMU, brand_enum::KVM, brand_enum::KVM_HYPERV, brand_enum::QEMU_KVM_HYPERV },
47514751
47524752 // VMware merges
@@ -4966,79 +4966,53 @@ struct VM {
49664966 * @category x86
49674967 * @implements VM::CPU_BRAND
49684968 */
4969- [[nodiscard]] static bool cpu_brand() {
4969+ [[nodiscard]] static bool cpu_brand() {
49704970 #if (!x86)
4971- return false;
4971+ return false;
49724972 #else
4973- const std::string& brand = cpu::get_brand();
4974-
4975- // easy shortcut for QEMU
4976- if (brand.rfind("QEMU Virtual CPU version", 0) == 0) {
4977- return core::add(brand_enum::QEMU);
4978- }
4979-
4980- struct cstrview {
4981- const char* data;
4982- std::size_t size;
4983- constexpr cstrview(const char* d, std::size_t s) noexcept
4984- : data(d), size(s) {
4985- }
4986- };
4973+ const char* brand = cpu::get_brand();
49874974
4988- static constexpr std::array<cstrview, 10> checks{ {
4989- { "qemu", 4 },
4990- { "kvm", 3 },
4991- { "vbox", 4 },
4992- { "virtualbox", 10},
4993- { "monitor", 7 },
4994- { "bhyve", 5 },
4995- { "hypervisor", 10},
4996- { "hvisor", 6 },
4997- { "parallels", 9 },
4998- { "vmware", 6 }
4999- } };
5000-
5001- for (auto& v : checks) {
5002- if (brand.size() < v.size) {
5003- continue; // too short to match
5004- }
4975+ if (!brand) {
4976+ return false;
4977+ }
50054978
5006- if (brand.find(v.data) != std::string::npos) {
5007- debug("CPU_BRAND: match = ", v.data);
4979+ if (strncmp(brand, "QEMU Virtual CPU version", 24) == 0) {
4980+ return core::add(brand_enum::QEMU);
4981+ }
50084982
5009- // For these, we only care that it's virtualized:
5010- if (v.size == 7 // "monitor"
5011- || ((v.size == 6) && (v.data[0] == 'h')) // "hvisor"
5012- || ((v.size == 10) && (v.data[0] == 'h')) // "hypervisor"
5013- ) {
5014- return true;
5015- }
4983+ struct check_t {
4984+ const char* text;
4985+ brand_enum brand;
4986+ };
4987+
4988+ static constexpr check_t checks[] = {
4989+ { "qemu", brand_enum::QEMU },
4990+ { "kvm", brand_enum::KVM },
4991+ { "vbox", brand_enum::VBOX },
4992+ { "virtualbox", brand_enum::VBOX },
4993+ { "bhyve", brand_enum::BHYVE },
4994+ { "parallels", brand_enum::PARALLELS },
4995+ { "vmware", brand_enum::VMWARE },
4996+ };
4997+
4998+ for (const auto& c : checks) {
4999+ if (strstr(brand, c.text)) {
5000+ debug("CPU_BRAND: match = ", c.text);
5001+ return core::add(c.brand);
5002+ }
5003+ }
50165004
5017- // Otherwise map to our enums:
5018- switch (v.size) {
5019- case 4: // "qemu" or "vbox"
5020- return core::add(v.data[0] == 'q'
5021- ? brand_enum::QEMU
5022- : brand_enum::VBOX);
5023- case 3: // "kvm"
5024- return core::add(brand_enum::KVM);
5025- case 5: // "bhyve"
5026- return core::add(brand_enum::BHYVE);
5027- case 9: // "parallels"
5028- return core::add(brand_enum::PARALLELS);
5029- case 10: // "virtualbox"
5030- return core::add(brand_enum::VBOX);
5031- case 6: // "vmware"
5032- return core::add(brand_enum::VMWARE);
5033- default:
5034- return false;
5035- }
5036- }
5037- }
5005+ if (strstr(brand, "monitor") ||
5006+ strstr(brand, "hypervisor") ||
5007+ strstr(brand, "hvisor"))
5008+ {
5009+ debug("CPU_BRAND: generic virtualization match");
5010+ return true;
5011+ }
50385012
5039- return false;
5013+ return false;
50405014 #endif
5041- }
5015+ }
50425016
50435017
50445018 /**
0 commit comments