From: Lennart Poettering Date: Mon, 4 Apr 2022 08:29:40 +0000 (+0200) Subject: virt: rework kvm with hyperv enlightenment checks a bit X-Git-Tag: v251-rc2~212^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0f534758d1d652824fb554e90bc2075218b9c884;p=thirdparty%2Fsystemd.git virt: rework kvm with hyperv enlightenment checks a bit Let's avoid extending the virtualization with an "alias" entry that has the same string assigned as another. The only reason this was done was to make the patch small that added a second CPUID vendor string for kvm to the vm_table[] array. Let's instead rework the array to use struct elements that match up strings with ids. Given the array was previously mostly sparse this should be a general improvement. Fixes: #22950 Follow-up for: #22945 --- diff --git a/src/basic/virt.c b/src/basic/virt.c index 4cf8691c27d..9bef46c9d1a 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -28,31 +28,30 @@ enum { SMBIOS_VM_BIT_UNKNOWN, }; -#if defined(__i386__) || defined(__x86_64__) -static const char *const vm_table[_VIRTUALIZATION_MAX] = { - [VIRTUALIZATION_XEN] = "XenVMMXenVMM", - [VIRTUALIZATION_KVM] = "KVMKVMKVM", - [VIRTUALIZATION_HV_KVM] = "Linux KVM Hv", - [VIRTUALIZATION_QEMU] = "TCGTCGTCGTCG", - /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ - [VIRTUALIZATION_VMWARE] = "VMwareVMware", - /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */ - [VIRTUALIZATION_MICROSOFT] = "Microsoft Hv", - /* https://wiki.freebsd.org/bhyve */ - [VIRTUALIZATION_BHYVE] = "bhyve bhyve ", - [VIRTUALIZATION_QNX] = "QNXQVMBSQG", - /* https://projectacrn.org */ - [VIRTUALIZATION_ACRN] = "ACRNACRNACRN", -}; - -DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(vm, int); -#endif - static int detect_vm_cpuid(void) { /* CPUID is an x86 specific interface. */ #if defined(__i386__) || defined(__x86_64__) + static const struct { + const char sig[13]; + int id; + } vm_table[] = { + { "XenVMMXenVMM", VIRTUALIZATION_XEN }, + { "KVMKVMKVM", VIRTUALIZATION_KVM }, /* qemu with KVM */ + { "Linux KVM Hv", VIRTUALIZATION_KVM }, /* qemu with KVM + HyperV Enlightenments */ + { "TCGTCGTCGTCG", VIRTUALIZATION_QEMU }, /* qemu without KVM */ + /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */ + { "VMwareVMware", VIRTUALIZATION_VMWARE }, + /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */ + { "Microsoft Hv", VIRTUALIZATION_MICROSOFT }, + /* https://wiki.freebsd.org/bhyve */ + { "bhyve bhyve ", VIRTUALIZATION_BHYVE }, + { "QNXQVMBSQG", VIRTUALIZATION_QNX }, + /* https://projectacrn.org */ + { "ACRNACRNACRN", VIRTUALIZATION_ACRN }, + }; + uint32_t eax, ebx, ecx, edx; bool hypervisor; @@ -69,7 +68,6 @@ static int detect_vm_cpuid(void) { uint32_t sig32[3]; char text[13]; } sig = {}; - int v; /* There is a hypervisor, see what it is */ __cpuid(0x40000000U, eax, ebx, ecx, edx); @@ -80,11 +78,13 @@ static int detect_vm_cpuid(void) { log_debug("Virtualization found, CPUID=%s", sig.text); - v = vm_from_string(sig.text); - if (v < 0) - return VIRTUALIZATION_VM_OTHER; + for (size_t i = 0; i < ELEMENTSOF(vm_table); i++) + if (memcmp_nn(sig.text, sizeof(sig.text), + vm_table[i].sig, sizeof(vm_table[i].sig)) == 0) + return vm_table[i].id; - return v; + log_debug("Unknown virtualization with CPUID=%s. Add to vm_table[]?", sig.text); + return VIRTUALIZATION_VM_OTHER; } #endif log_debug("No virtualization found in CPUID"); @@ -996,7 +996,6 @@ bool has_cpu_with_flag(const char *flag) { static const char *const virtualization_table[_VIRTUALIZATION_MAX] = { [VIRTUALIZATION_NONE] = "none", [VIRTUALIZATION_KVM] = "kvm", - [VIRTUALIZATION_HV_KVM] = "kvm", [VIRTUALIZATION_AMAZON] = "amazon", [VIRTUALIZATION_QEMU] = "qemu", [VIRTUALIZATION_BOCHS] = "bochs", diff --git a/src/basic/virt.h b/src/basic/virt.h index 0b78d1baa36..1eafbe2cbec 100644 --- a/src/basic/virt.h +++ b/src/basic/virt.h @@ -10,7 +10,6 @@ enum { VIRTUALIZATION_VM_FIRST, VIRTUALIZATION_KVM = VIRTUALIZATION_VM_FIRST, - VIRTUALIZATION_HV_KVM, VIRTUALIZATION_AMAZON, VIRTUALIZATION_QEMU, VIRTUALIZATION_BOCHS, diff --git a/src/test/test-tables.c b/src/test/test-tables.c index 62b0ba9411b..3e5df045900 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -121,6 +121,7 @@ int main(int argc, char **argv) { test_table(unit_file_state, UNIT_FILE_STATE); test_table(unit_load_state, UNIT_LOAD_STATE); test_table(unit_type, UNIT_TYPE); + test_table(virtualization, VIRTUALIZATION); test_table_sparse(object_compressed, OBJECT_COMPRESSED);