From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:26 +0000 (-0700) Subject: Hostinfo hypervisor detection changes. X-Git-Tag: stable-10.2.0~333 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2bf0056a956888da2aeb07f62b4ae05f5cb5427e;p=thirdparty%2Fopen-vm-tools.git Hostinfo hypervisor detection changes. --- diff --git a/open-vm-tools/lib/include/hostinfo.h b/open-vm-tools/lib/include/hostinfo.h index dbb87e3ee..abba8e3bb 100644 --- a/open-vm-tools/lib/include/hostinfo.h +++ b/open-vm-tools/lib/include/hostinfo.h @@ -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 diff --git a/open-vm-tools/lib/misc/hostinfoHV.c b/open-vm-tools/lib/misc/hostinfoHV.c index 84a2000c0..1c616d236 100644 --- a/open-vm-tools/lib/misc/hostinfoHV.c +++ b/open-vm-tools/lib/misc/hostinfoHV.c @@ -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 @@ -37,6 +37,38 @@ #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; +} + + /* *---------------------------------------------------------------------- * @@ -61,20 +93,14 @@ Hostinfo_HypervisorCPUIDSig(void) #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); @@ -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, ®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; +} + + /* *---------------------------------------------------------------------- *