From: Lennart Poettering Date: Fri, 19 Apr 2024 11:25:55 +0000 (+0200) Subject: detect-virt: detect hyperv-enlightened qemu as qemu, not as hyperv X-Git-Tag: v256-rc1~93^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cea9216a42bddee3621e2e6c3a56a1ec9ce90dd0;p=thirdparty%2Fsystemd.git detect-virt: detect hyperv-enlightened qemu as qemu, not as hyperv CPUID reporting hyperv should be taken with a grain of salt, and we should prefer other mechanisms then. Fixes: #28001 --- diff --git a/src/basic/virt.c b/src/basic/virt.c index 7e2c0781fe1..09703506f93 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -447,7 +447,7 @@ static Virtualization detect_vm_zvm(void) { /* Returns a short identifier for the various VM implementations */ Virtualization detect_vm(void) { static thread_local Virtualization cached_found = _VIRTUALIZATION_INVALID; - bool other = false; + bool other = false, hyperv = false; int xen_dom0 = 0; Virtualization v, dmi; @@ -504,7 +504,12 @@ Virtualization detect_vm(void) { v = detect_vm_cpuid(); if (v < 0) return v; - if (v == VIRTUALIZATION_VM_OTHER) + if (v == VIRTUALIZATION_MICROSOFT) + /* QEMU sets the CPUID string to hyperv's, in case it provides hyperv enlightenments. Let's + * hence not return Microsoft here but just use the other mechanisms first to make a better + * decision. */ + hyperv = true; + else if (v == VIRTUALIZATION_VM_OTHER) other = true; else if (v != VIRTUALIZATION_NONE) goto finish; @@ -545,8 +550,15 @@ Virtualization detect_vm(void) { return v; finish: - if (v == VIRTUALIZATION_NONE && other) - v = VIRTUALIZATION_VM_OTHER; + /* None of the checks above gave us a clear answer, hence let's now use fallback logic: if hyperv + * enlightenments are available but the VMM wasn't recognized as anything yet, it's probably + * Microsoft. */ + if (v == VIRTUALIZATION_NONE) { + if (hyperv) + v = VIRTUALIZATION_MICROSOFT; + else if (other) + v = VIRTUALIZATION_VM_OTHER; + } cached_found = v; log_debug("Found VM virtualization %s", virtualization_to_string(v));