/*********************************************************
- * Copyright (C) 2011-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2017 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
#include "loglevel_user.h"
+/*
+ *----------------------------------------------------------------------
+ *
+ * Hostinfo_HypervisorPresent --
+ *
+ * Check if hypervisor is present.
+ *
+ * Results:
+ * TRUE iff hypervisor cpuid bit is present.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Bool
+Hostinfo_HypervisorPresent(void)
+{
+ static Bool hypervisorPresent;
+#if defined(__i386__) || defined(__x86_64__)
+ CPUIDRegs regs;
+
+ if (!hypervisorPresent) {
+ __GET_CPUID(1, ®s);
+ hypervisorPresent = CPUID_ISSET(1, ECX, HYPERVISOR, regs.ecx);
+ }
+#endif
+ return hypervisorPresent;
+}
+
+
/*
*----------------------------------------------------------------------
*
#if defined(__i386__) || defined(__x86_64__)
CPUIDRegs regs;
- __GET_CPUID(1, ®s);
- if (!CPUID_ISSET(1, ECX, HYPERVISOR, regs.ecx)) {
+ if (!Hostinfo_HypervisorPresent()) {
return NULL;
}
- regs.ebx = 0;
- regs.ecx = 0;
- regs.edx = 0;
-
__GET_CPUID(0x40000000, ®s);
-
if (regs.eax < 0x40000000) {
Log(LGPFX" CPUID hypervisor bit is set, but no "
- "hypervisor vendor signature is present\n");
+ "hypervisor vendor signature is present.\n");
}
name = Util_SafeMalloc(4 * sizeof *name);
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * Hostinfo_LogHypervisorCPUID --
+ *
+ * Logs hypervisor CPUID leafs.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Hostinfo_LogHypervisorCPUID(void)
+{
+#if defined(__i386__) || defined(__x86_64__)
+ CPUIDRegs regs;
+ uint32 maxLeaf;
+ uint32 leafId;
+ if (!Hostinfo_HypervisorPresent()) {
+ Log(LGPFX" Hypervisor not found. CPUID hypervisor bit is not set.\n");
+ return;
+ }
+
+ __GET_CPUID(0x40000000, ®s);
+ maxLeaf = regs.eax > 0x400000FF ? 0x400000FF : regs.eax;
+ if (maxLeaf < 0x40000000) {
+ Log(LGPFX" CPUID hypervisor bit is set, but no "
+ "hypervisor vendor signature is present.\n");
+ return;
+ } else {
+ Log("CPUID level %10s %10s %10s %10s\n", "EAX", "EBX",
+ "ECX", "EDX");
+ for (leafId = 0x40000000; leafId <= maxLeaf; leafId++) {
+ __GET_CPUID(leafId, ®s);
+ Log("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ leafId, regs.eax, regs.ebx, regs.ecx, regs.edx);
+ }
+ }
+#endif // defined(__i386__) || defined(__x86_64__)
+
+ return;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Hostinfo_HypervisorInterfaceSig --
+ *
+ * Get hypervisor interface signature string from CPUID.
+ *
+ * Results:
+ * Unqualified 8 byte nul-terminated hypervisor interface signature string.
+ * String may contain garbage and caller must free.
+ * NULL if hypervisor is not present.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Hostinfo_HypervisorInterfaceSig(void)
+{
+ uint32 *intrSig = NULL;
+#if defined(__i386__) || defined(__x86_64__)
+ CPUIDRegs regs;
+
+ if (!Hostinfo_HypervisorPresent()) {
+ return NULL;
+ }
+
+ __GET_CPUID(0x40000000, ®s);
+ if (regs.eax < 0x40000001) {
+ Log(LGPFX" CPUID hypervisor bit is set, but no "
+ "hypervisor interface signature is present.\n");
+ return NULL;
+ }
+
+ __GET_CPUID(0x40000001, ®s);
+ if (regs.eax != 0) {
+ intrSig = Util_SafeMalloc(2 * sizeof *intrSig);
+ intrSig[0] = regs.eax;
+ intrSig[1] = 0;
+ }
+#endif // defined(__i386__) || defined(__x86_64__)
+
+ return (char *)intrSig;
+}
+
+
/*
*----------------------------------------------------------------------
*