}
static int detect_vm_xen(void) {
- int r;
-
- /* The presence of /proc/xen indicates some form of a Xen domain */
+ /* The presence of /proc/xen indicates some form of a Xen domain
+ The check for Dom0 is handled outside this function */
if (access("/proc/xen", F_OK) < 0) {
log_debug("Virtualization XEN not found, /proc/xen does not exist");
return VIRTUALIZATION_NONE;
}
log_debug("Virtualization XEN found (/proc/xen exists)");
-
- /* Ignore the Xen hypervisor if we are in Dom0 */
- r = detect_vm_xen_dom0();
- if (r < 0)
- return r;
- if (r > 0)
- return VIRTUALIZATION_NONE;
-
return VIRTUALIZATION_XEN;
}
int detect_vm(void) {
static thread_local int cached_found = _VIRTUALIZATION_INVALID;
bool other = false;
- int r, dmi;
+ int r, dmi, xen_dom0 = 0;
if (cached_found >= 0)
return cached_found;
r = detect_vm_uml();
if (r < 0)
return r;
- if (r == VIRTUALIZATION_VM_OTHER)
- other = true;
- else if (r != VIRTUALIZATION_NONE)
+ if (r != VIRTUALIZATION_NONE)
goto finish;
/* Detect Xen */
r = detect_vm_xen();
if (r < 0)
return r;
- if (r == VIRTUALIZATION_VM_OTHER)
- other = true;
- else if (r != VIRTUALIZATION_NONE)
- goto finish;
+ if (r == VIRTUALIZATION_XEN) {
+ /* If we are Dom0, then we expect to not report as a VM. However, as we might be nested
+ * inside another hypervisor which can be detected via the CPUID check, wait to report this
+ * until after the CPUID check. */
+ xen_dom0 = detect_vm_xen_dom0();
+ if (xen_dom0 < 0)
+ return xen_dom0;
+ if (xen_dom0 == 0)
+ goto finish;
+
+ r = VIRTUALIZATION_NONE;
+ } else if (r != VIRTUALIZATION_NONE)
+ assert_not_reached();
/* Detect from CPUID */
r = detect_vm_cpuid();
else if (r != VIRTUALIZATION_NONE)
goto finish;
+ /* If we are in Dom0 and have not yet finished, finish with the result of detect_vm_cpuid */
+ if (xen_dom0 > 0)
+ goto finish;
+
/* Now, let's get back to DMI */
if (dmi < 0)
return dmi;