virt: Properly detect nested UML inside another hypervisor

UML runs as a user-process so it can quite easily be ran inside of
another hypervisor, for instance inside a KVM instance. UML passes
through the CPUID from the host machine so in this case detect_vm
incorrectly identifies as running under KVM. So check we are running
a UML kernel first, before we check any other hypervisors.

Resolves: #17754

Signed-off-by: Christopher Obbard <chris.obbard@collabora.com>
This commit is contained in:
Christopher Obbard 2020-12-02 14:20:39 +00:00 committed by Yu Watanabe
parent 0b261ac5be
commit c8037dbf05
1 changed files with 11 additions and 9 deletions

View File

@ -345,7 +345,7 @@ int detect_vm(void) {
/* We have to use the correct order here:
*
* First, try to detect Oracle Virtualbox, even if it uses KVM, as well as Xen even if it cloaks as Microsoft
* Hyper-V.
* Hyper-V. Attempt to detect uml at this stage also since it runs as a user-process nested inside other VMs.
*
* Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is
* overwritten.
@ -358,6 +358,16 @@ int detect_vm(void) {
goto finish;
}
/* Detect UML */
r = detect_vm_uml();
if (r < 0)
return r;
if (r == VIRTUALIZATION_VM_OTHER)
other = true;
else if (r != VIRTUALIZATION_NONE)
goto finish;
/* Detect from CPUID */
r = detect_vm_cpuid();
if (r < 0)
return r;
@ -406,14 +416,6 @@ int detect_vm(void) {
else if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_uml();
if (r < 0)
return r;
if (r == VIRTUALIZATION_VM_OTHER)
other = true;
else if (r != VIRTUALIZATION_NONE)
goto finish;
r = detect_vm_zvm();
if (r < 0)
return r;