#endif
}
-static int detect_vm_xen(void) {
-
- /* Check for Dom0 will be executed later in detect_vm_xen_dom0
- The presence of /proc/xen indicates some form of a Xen domain */
- 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)");
- return VIRTUALIZATION_XEN;
-}
-
#define XENFEAT_dom0 11 /* xen/include/public/features.h */
#define PATH_FEATURES "/sys/hypervisor/properties/features"
/* Returns -errno, or 0 for domU, or 1 for dom0 */
}
}
+static int detect_vm_xen(void) {
+ int r;
+
+ /* The presence of /proc/xen indicates some form of a Xen domain */
+ 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;
+}
+
static int detect_vm_hypervisor(void) {
_cleanup_free_ char *hvtype = NULL;
int r;
*
* → First, try to detect Oracle Virtualbox and Amazon EC2 Nitro, even if they use KVM, as well as Xen even if
* it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also since it runs as a user-process
- * nested inside other VMs.
+ * nested inside other VMs. Also check for Xen now, because Xen PV mode does not override CPUID when nested
+ * inside another hypervisor.
*
* → Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is
* overwritten.
else 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;
+
/* Detect from CPUID */
r = detect_vm_cpuid();
if (r < 0)
goto finish;
}
- /* x86 xen will most likely be detected by cpuid. If not (most likely
- * because we're not an x86 guest), then we should try the /proc/xen
- * directory next. If that's not found, then we check for the high-level
- * hypervisor sysfs file.
- */
-
- r = detect_vm_xen();
- if (r < 0)
- return r;
- if (r == VIRTUALIZATION_VM_OTHER)
- other = true;
- else if (r != VIRTUALIZATION_NONE)
- goto finish;
-
+ /* Check high-level hypervisor sysfs file */
r = detect_vm_hypervisor();
if (r < 0)
return r;
return r;
finish:
- /* x86 xen Dom0 is detected as XEN in hypervisor and maybe others.
- * In order to detect the Dom0 as not virtualization we need to
- * double-check it */
- if (r == VIRTUALIZATION_XEN) {
- int dom0;
-
- dom0 = detect_vm_xen_dom0();
- if (dom0 < 0)
- return dom0;
- if (dom0 > 0)
- r = VIRTUALIZATION_NONE;
- } else if (r == VIRTUALIZATION_NONE && other)
+ if (r == VIRTUALIZATION_NONE && other)
r = VIRTUALIZATION_VM_OTHER;
cached_found = r;