]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Hostinfo hypervisor detection changes.
authorOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:26 +0000 (11:23 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:26 +0000 (11:23 -0700)
open-vm-tools/lib/include/hostinfo.h
open-vm-tools/lib/misc/hostinfoHV.c

index dbb87e3ee03f7159400e6aa3f01f873c702d1544..abba8e3bb7ea18ea786988fe4b9d928831b7deb1 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 1998-2016 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-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
@@ -128,6 +128,8 @@ Bool Hostinfo_TouchBackDoor(void);
 Bool Hostinfo_TouchVirtualPC(void);
 Bool Hostinfo_TouchXen(void);
 char *Hostinfo_HypervisorCPUIDSig(void);
+void Hostinfo_LogHypervisorCPUID(void);
+char *Hostinfo_HypervisorInterfaceSig(void);
 
 #define HGMP_PRIVILEGE    0
 #define HGMP_NO_PRIVILEGE 1
index 84a2000c0c2b78fa537e54d0a1a6834fe8b5a19f..1c616d236967b2623442cd4a51a60dbff59faa0b 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * 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, &regs);
+      hypervisorPresent = CPUID_ISSET(1, ECX, HYPERVISOR, regs.ecx);
+   }
+#endif
+   return hypervisorPresent;
+}
+
+
 /*
  *----------------------------------------------------------------------
  *
@@ -61,20 +93,14 @@ Hostinfo_HypervisorCPUIDSig(void)
 #if defined(__i386__) || defined(__x86_64__)
    CPUIDRegs regs;
 
-   __GET_CPUID(1, &regs);
-   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, &regs);
-
    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);
@@ -89,6 +115,100 @@ Hostinfo_HypervisorCPUIDSig(void)
 }
 
 
+/*
+ *----------------------------------------------------------------------
+ *
+ *  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, &regs);
+   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, &regs);
+         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, &regs);
+   if (regs.eax < 0x40000001) {
+      Log(LGPFX" CPUID hypervisor bit is set, but no "
+          "hypervisor interface signature is present.\n");
+      return NULL;
+   }
+
+   __GET_CPUID(0x40000001, &regs);
+   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;
+}
+
+
 /*
  *----------------------------------------------------------------------
  *